I Have the php code :
$rand = rand(1,5);
and I want to define var that has the name of the rand function like :
$$rand // if $rand= 1 then the var will be $1
and then do
switch($rand){
case(1):
$$rand = 'How many legs dog has ?';
$ans= '4'; }
The code is for defining security questions.
Hope someone got my idea. How can I do it ?
Sometimes it is convenient to be able to have variable variable names. That is, a variable name which can be set and used dynamically. A normal variable is set with a statement such as:
<?php
$a = 'hello';
?>
A variable variable takes the value of a variable and treats that as the name of a variable. In the above example, hello, can be used as the name of a variable by using two dollar signs. i.e.
<?php
$$a = 'world';
?>
At this point two variables have been defined and stored in the PHP symbol tree: $a with contents "hello" and $hello with contents "world". Therefore, this statement:
<?php
echo "$a ${$a}";
?>
produces the exact same output as:
<?php
echo "$a $hello";
?>
i.e. they both produce: hello world.
In order to use variable variables with arrays, you have to resolve an ambiguity problem. That is, if you write $$a[1] then the parser needs to know if you meant to use $a[1] as a variable, or if you wanted $$a as the variable and then the [1] index from that variable. The syntax for resolving this ambiguity is: ${$a[1]} for the first case and ${$a}[1] for the second.
Class properties may also be accessed using variable property names. The variable property name will be resolved within the scope from which the call is made. For instance, if you have an expression such as $foo->$bar, then the local scope will be examined for $bar and its value will be used as the name of the property of $foo. This is also true if $bar is an array access.
// Sanitize the arrays
$questions = array();
$answers = array();
// Build some questions and assign to the questions array
$questions[0] = 'How many legs does a dog have?';
$questions[1] = 'How many eyes does a human have?';
$questions[2] = 'How many legs does a spider have?';
// Add the answers, making sure the array index is the same as the questions array
$answers[0] = 4;
$answers[1] = 2;
$answers[2] = 8;
// Select a question to use
$questionId = rand(0, count($questions));
// Output the question and answer
echo 'questions: ' . $questions[$questionId];
echo 'answer: ' . $answers[$questionId];
Variables in PHP cannot start with a number.
${$rand} is the right way. Do note, however, that your variable name cannot start with a number.
Quoting the php manual:
Variable names follow the same rules as other labels in PHP. A valid variable name starts with a letter or underscore, followed by any number of letters, numbers, or underscores. As a regular expression, it would be expressed thus: '[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*'
Related
I'm not even sure if what I am trying to do is possible, I have a simple php echo line as below..
<?php echo $T1R[0]['Site']; ?>
This works well but I want to make the "1" in the $T1R to be fluid, is it possible to do something like ..
<?php echo $T + '$row_ColNumC['ColNaumNo']' + R[0]['Site']; ?>
Where the 1 is replaced with the content of ColNaumNo i.e. the returned result might be..
<?php echo $T32R[0]['Site']; ?>
It is possible in PHP. The concept is called "variable variables".
The idea is simple: you generate the variable name you want to use and store it in another variable:
$name = 'T'.$row_ColNumC['ColNaumNo'].'R';
Pay attention to the string concatenation operator. PHP uses a dot (.) for this, not the plus sign (+).
If the value of $row_ColNumc['ColNaumNo'] is 32 then the value stored in variable $name is 'T32R';
You can then prepend the variable $name with an extra $ to use it as the name of another variable (indirection). The code echo($$name); prints the content of variable $T32R (if any).
If the variable $T32R stores an array then the syntax $$name[0] is ambiguous and the parser needs a hint to interpret it. It is well explained in the documentation page (of the variable variables):
In order to use variable variables with arrays, you have to resolve an ambiguity problem. That is, if you write $$a[1] then the parser needs to know if you meant to use $a[1] as a variable, or if you wanted $$a as the variable and then the [1] index from that variable. The syntax for resolving this ambiguity is: ${$a[1]} for the first case and ${$a}[1] for the second.
You can do like this
$T1R[0]['Site'] = "test";
$c = 1;
$a = "T".$c."R";
$b = $$a;
echo "<pre>";
print_r($b[0]['Site']);
Or more simpler like this
$T1R[0]['Site'] = "test";
$c = 1;
$a = "T".$c."R";
echo "<pre>";
print_r(${$a}[0]['Site']);
I'm new to OOP in PHP and I find the difference between the following two expressions difficult to understand.
$object->$foo;
$object->foo;
Maybe it's my fault, but I could not find the relevant part in the manual.
The first call $obj->$foo is using a so called variable variable. Check this:
class A {
public $foo = 1;
}
$a = new A();
$foo = 'foo';
// now you can use both
echo $a->$foo;
echo $a->foo;
Follow the manual about variable variables
Well, in order to fully understand the somewhat odd-looking $object->$foo, you should understand two things about PHP:
Variable names
Most of the time variables in PHP are quite straight-forward. They begin with a $ sign, have one [a-zA-Z_] character, and then any amount of [a-z-A-Z0-9_] characters. Examples include:
$var = 'Abcdef';
$_GET = [];
$a1 = 123;
// And so on...
Now, PHP variables can actually be named pretty much anything, as long as the name is, or can be cast to, a scalar type. The way you name a variable with anything is to use curly braces ({}), like this:
${null} = 'It works'; echo ${null};
${false} = 'It works'; echo ${false};
${'!'} = 'It works'; echo ${'!'};
// Slightly weirder...
${(int)trim(' 5 ')} = 'It works'; echo ${5};
${implode(['a','b','c'])} = 'It works'; echo $abc;
Important: Just because you can do this does not mean you should, however. It is mostly just an oddity of PHP that you can do this.
Variable variables
A somewhat convoluted explanation: A variable variable is a variable that is accessed using a variable name.
A much easier way to understand variable variables is to use what we just learning about variable names in PHP. Take this example:
${"abc"} = 'Abc...';
echo $abc;
We create a variable using the string, "abc", which can also be accessed using $abc.
Now, there is no reason (or rule) that says it has to be a string.... it can also be a variable:
$abc = 'Abc...';
$varName = 'abc';
echo ${$varName}; // echo $abc
That is basically a variable variable. "Real" variable variables just do not use the curly braces:
$abc = 'Abc...';
$varName = 'abc';
echo $$varName; // echo $abc
As for the question
In the question the $object->$foo thing is basically just an "object variable variable", if you like
$object = new stdClass;
$object->abc = 'The alphabet!';
$foo = 'abc';
echo $object->$foo;
echo $object->{$foo}; // The same
echo $object->{'abc'}; // The same
Object variable variables can be somewhat useful, but they are rarely necessary. Using an associative array is usually a better choice.
$arr[0]=123;
$a="arr[0]";
echo $$a;
gives me error
Notice: Undefined variable: arr[0]
on the last line.
What should I do to make it work?
EDIT:
Above is the simplification of what I want to do. If someone wants to know why I want to do this, then here's the explanation:
This is something like what I want to do:
if(condition){
$a=$arr1[0][0];
$b=$arr1[0][1];
$c=$arr1[0][2];
}
else{
$a=$arr2[0];
$b=$arr2[1];
$c=$arr2[2];
}
I can compact it like this:
if(condition)
$arr=$arr1[0];
else
$arr=$arr2;
$a=$arr[0];
$a=$arr[1];
$a=$arr[2];
But I wanted to try doing this using variable variable:
if(condition)
$arr="$arr1[0]";
else
$arr="$arr2";
$a={$$arr}[0];
$b={$$arr}[1];
$c={$$arr}[2];
Sure, we don't need variable variables as we can still code without them. I want to know, for learning PHP, why the code won't work.
Now that you said what you’re actually trying to accomplish: Your code doesn’t work because if you look at $arr1[0][0], only arr is the variable name; the [0] are special accessors for certain types like strings or arrays.
With variable variables you can only specify the name but not any accessor or other operation:
A variable variable takes the value of a variable and treats that as the name of a variable.
Your solution with the additional variable holding the array to access later on would be the best solution to your problem.
What you are trying to do just won't work - the code $arr[0] is referencing a variable called $arr, and then applying the array-access operator ([$key]) to get the element with key 0. There is no variable called $arr[0], so you cannot reference it with variable-variables any more than you could the expression $foo + 1 .
The real question is why you want to do this; variable variables are generally a sign of very messy code, and probably some poor choices of data structure. For instance, if you need to select one of a set of variables based on some input, you probably want a hash, and to look up an item using $hash[$item] or similar. If you need something more complex, a switch statement can often cover the cases you actually need.
If for some reason you really need to allow an arbitrary expression like $arr[0] as input and evaluate it at runtime, you could use eval(), but be very very careful of where the input is coming from, as this can be a very easy way of introducing security holes into your code.
FROM PHP DOC
In order to use variable variables with arrays, you have to resolve an ambiguity problem. That is, if you write $$a[1] then the parser needs to know if you meant to use $a[1] as a variable, or if you wanted $$a as the variable and then the [1] index from that variable. The syntax for resolving this ambiguity is: ${$a[1]} for the first case and ${$a}[1] for the second.
Use
echo ${$a}[0]; // 123
Edit : Based on your edit you can simply have
list($a, $b, $c) = (condition) ? $arr1[0] : $arr2;
Or
$array = (condition) ? $arr1[0] : $arr2;
$a = $array[0];
$b = $array[1];
$c = $array[2];
As pointed out you don't need variable variables. To get a PHP variable variable name containing index (a key) use array_keys() or array_search() or other array parsers. From php's site:
$array = array(0 => 'blue', 1 => 'red', 2 => 'green', 3 => 'red');
$key = array_search('green', $array); // $key = 2;
$key = array_search('red', $array); // $key = 1;
You could also use the following (using $var= instead of echo):
$arr[0]=123;
$arr[1]=456;
foreach ($arr as $key => $value) {
echo "arr[{$key}] = {$value} \r\n";
}
Which outputs:
arr[0] = 123
arr[1] = 456
But I don't see why you'd do that, since the whole point of the array is not doing that kind of stuff.
I understand the usage of complex (curly) syntax within a string, but I don't understand it's purpose outside of a string.
I just found this code in CakePHP that I cannot understand:
// $class is a string containg a class name
${$class} =& new $class($settings);
If somebody could help me understand why is used here, and what is the difference between this and:
$class =& new $class($settings);
Thank you.
Easiest way to understand this is by example:
class FooBar { }
// This is an ordinary string.
$nameOfClass = "FooBar";
// Make a variable called (in this case) "FooBar", which is the
// value of the variable $nameOfClass.
${$nameOfClass} = new $nameOfClass();
if(isset($FooBar))
echo "A variable called FooBar exists and its class name is " . get_class($FooBar);
else
echo "No variable called FooBar exists.";
Using ${$something} or $$something. is referred to in PHP as a "variable variable".
So in this case, a new variable called $FooBar is created and the variable $nameOfClass is still just a string.
An example where the usage of the complex (curly) syntax outside of a string would be necessary is when forming a variable name out of an expression, consisting of more than just one variable. Consider the following code:
$first_name="John";
$last_name="Doe";
$array=['first','last'];
foreach ($array as $element) {
echo ${$element.'_name'}.' ';
}
In the code above the echo statement will output the value of the variable $first_name during the first loop, and the value of the variable $last_name during the second loop. If you were to remove the curly brackets the echo statement would try to output the value of the variable $first during the first loop and the value of the variable $last during the second loop. But since these variables were not defined the code would return an error.
The first example creates a dynamically named variable (name is the value of the class variable), the other overwrites the value of the class variable.
The title may be a little confusing. This is my problem:
I know you can hold a variable name in another variable and then read the content of the first variable. This is what I mean:
$variable = "hello"
$variableholder = 'variable'
echo $$variableholder;
That would print: "hello". Now, I've got a problem with this:
$somearray = array("name"=>"hello");
$variableholder = "somearray['name']"; //or $variableholder = 'somearray[\'name\']';
echo $$variableholder;
That gives me a PHP error (it says $somearray['name'] is an undefined variable). Can you tell me if this is possible and I'm doing something wrong; or this if this is plain impossible, can you give me another solution to do something similar?
Thanks in advance.
For the moment, I could only think of something like this:
<?php
// literal are simple
$literal = "Hello";
$vv = "literal";
echo $$vv . "\n";
// prints "Hello"
// for containers it's not so simple anymore
$container = array("Hello" => "World");
$vv = "container";
$reniatnoc = $$vv;
echo $reniatnoc["Hello"] . "\n";
// prints "World"
?>
The problem here is that (quoting from php: access array value on the fly):
the Grammar of the PHP language only allows subscript notation on the end of variable expressions and not expressions in general, which is how it works in most other languages.
Would PHP allow the subscript notation anywhere, one could write this more dense as
echo $$vv["Hello"]
Side note: I guess using variable variables isn't that sane to use in production.
How about this? (NOTE: variable variables are as bad as goto)
$variablename = 'array';
$key = 'index';
echo $$variablename[$key];