PHP: using variable value as variable name: curious about syntax issue - php

Suppose I have the following:
$foo = "bar";
$bar = "hello";
Then the string "hello" can be echoed to standard output as either:
echo $$foo;
or
echo ${$foo};
I was wondering what the difference is between these two statements in general.
That is, what is the purpose of the braces around the evaluated variable name
in the second syntax displayed above?

The only reason to use ${$foo} is to be able to combine $foo to something else, for example:
$idx = 4;
$bar3 = 20;
$bar4 = 7;
echo ${$foo.$idx}
This would return the value in $bar4 since $idx is worth 4;

There is no difference between the two in what they do in YOUR example.
The first example is concept knows as Variable Variables while the second braces example allows you to generate dynamic variables based on specified values.
You may also want to checkout:
PHP Variable Names: Curly Brace Madness
Accessibility and Dynamic Variable names

Related

PHP - Difference in creating variable variables with brackets or double dollar signs?

From what I can tell in the PHP Manual, it doesn't seem like there is much difference between defining a variable variable with double brackets or double dollar signs.
$foo = 'hello';
$$foo = 'hi';
echo $hello; // 'hi'
$baz = 'goodbye';
${$baz} = 'bye';
echo $goodbye; // 'bye'
The only difference it mentions in the manual is when using arrays. Is there any other noticeable difference between the two? Which one is better for which situations?
Both versions are basically the same.
The curly braces notation is used in cases where there could be ambiguity:
$foo = 'bar';
$bar = [];
${$foo}[] = 'foobar';
var_dump($bar); // foobar
If you'd omit the braces in the above example, you'd get a fatal error, with the braces, it works fine.
However, I would recommend avoiding dynamic variable names altogether. They are funny to use and may save some space. But in the end, your code will become less readable and you will have trouble debugging.
In this case, there is no difference. It is like using parentheses to group operators, even when they are not necessary.

Syntax for dynamic key name in fetch statement

I'm trying to modify the name of the key dynamically based on which rows are being fetched, but my syntax seems to be slightly off within the query. After moving the quotes around more times than I care to admit, I finally decided it was time to ask for help ;-)
$var = '$foo_row';
$MAX_5A = ${$var . '["MAX_5A"]'};
Instead of
$MAX_5A = $foo_row['MAX_5A'];
Bonus points if someone wants to explain to me the logic behind the correct syntax :-)
This should work for you:
(Just use variable variables with curly quotes to make sure PHP doesn't think this: ${$var["MAX_5A"]}. Also note I removed the dollar sign in the string)
$var = 'foo_row';
//^ dollar sign removed
$MAX_5A = ${$var}["MAX_5A"];
$var = 'foo';
$bar = 'var';
echo $$bar; // foo
Logic: A variable variable takes the value of a variable and treats that as the name of a variable.

What does { } do within a string?

$name = "jason";
$p = "hello-{hello2}-$name-{$name}";
echo $p;
output :
hello-{hello2}-jason-jason
Came across some examples of prepared statements and noticed this. If its encompassing a variable, it removes them, otherwise it keeps them. Why is this behavior necessary when
echo "$name";
gets you the same result as
echo "{$name}";
or is it just readability?
It's used as a delimiter for variables in strings. This is necessary in some cases, as PHP's string parser isn't Greedy aand will mis-interpret many common structs.
e.g.
$foo = array();
$foo['bar'] = array();
$foo['bar']['baz'] = 'qux';
echo "Hello $foo[bar][baz]";
will actually print
Hello Array[baz]
Because it's parsed as
echo "Hello ", $foo['bar'], "[baz]";
^ ^ ^
string array string
Using {} forces PHP to consider the array reference as single entity:
echo "Hello, {$foo['bar']['baz']}"; // prints "Hello, qux"
It also helps differentiate ambiguous stuff
$foo = 'bar';
echo "$foos" // undefined variable 'foos'
echo "{$foo}s" // variable containing 'bar' + string 's'
It's something called "complex syntax"
From php.net you can go to Complex (curly) syntax section and see many examples.
Complex (curly) syntax
This isn't called complex because the syntax is complex, but because it allows for the use of complex expressions.
Any scalar variable, array element or object property with a string representation can be included via this syntax. Simply write the expression the same way as it would appear outside the string, and then wrap it in { and }. Since { can not be escaped, this syntax will only be recognised when the $ immediately follows the {. Use {\$ to get a literal {$.
Functions, method calls, static class variables, and class constants inside {$} work since PHP 5. However, the value accessed will be interpreted as the name of a variable in the scope in which the string is defined. Using single curly braces ({}) will not work for accessing the return values of functions or methods or the values of class constants or static class variables.
It does not necessarily generate the same output:
$name = 'foo';
$names = 'bar';
echo "Output1: $names";
echo "Output2: {$name}s";
Output
Output1: bar
Output2: foos
Also you can access complex structures via the curly syntax like {$foo->bar}.
This syntax is useful when you want to display variable following some string and you don't want any space between them.
Compare the following:
<?php
$name='John';
echo "My name is $nameathan. I'm twenty years old<br />";
echo "My name is {$name}athan. I'm twenty years old<br />";
It will give you result:
Notice: Undefined variable: nameathan in ... on line 5
My name is . I'm twenty years old
My name is Johnathan. I'm twenty years old
For first echo it will generate notice and won't work as expected because PHP doesn't know that you want to use variable $name in the string and not $nameathan. Using curly braces in second case solves the issue.
Of course you can concatenate string this way:
echo "My name is $name"."athan. I'm twenty years old<br />";
and it also solves the issue but if you have many such variables in string it will be much more convenient to use curly braces.

PHP Globals and Reference Difference Confusion

Could some one please explain to me what the difference in the following is:
$var = 'something';
function myFunc(){
global $var;
// do something
}
and (note: the reference sign &)
$var = 'something';
function myFunc(&$var){
// do something
}
I can't understand the difference between these two methods.
Update
Hmmm... I think i'm getting alittle confused here :)
$var = 1;
$var2 = 2;
function myFunction(){
global $var, $var2;
$var = $var + $var2;
}
// echo $var would return 3 here.
$var = 1;
$var2 = 2;
function myFunction(&$a, &$b){
$a = $a + $b;
}
// echo $var would return 3 here aswell.
I understand those part already, But what i don't understand is the difference between these two approaches, am i wrong to assume that these two approaches are technically the same thing, with different concept of how they are wrote by the coder and also how they are handled by PHP?
If i'm wrong to assume this, then it would really help if you could provide better examples, maybe something that can be accomplished using only one of the above approaches?
ok, i noticed one difference while writing This Update, which is that when doing references i can chose new variable names while keeping the pointer to the variable in the functions scope.
In the second code block, the external $var and the internal $var are the same element. On the other hand, the third code block behaves a lot more like the first -- but you can access and modify the variable from the sending function; in the first code block, any edits you make to the variable internally are not available outside of the scope of the function.
EDIT to match the edits to the question.
The & means we are passing the variable by reference. The best way to describe it is by example.
function test2(&$var) { $var = 2; }
function test() {
$abc = 1;
test2($abc);
echo $abc;
}
test();
This code will print a 2 to the screen.
$var = 0;
function test()
{
global $var;
$var = 1;
}
test();
echo $var;
This will print 1;
In the first example, the local $var variable inside myFunc() will be assigned by reference to the variable with the same name that exists in the global scope (accessible through the superglobal $GLOBALS). PHP translates that to something like:
$var = 'something';
$GLOBALS['var'] = &$var;
function myFunc(){
$var = &$GLOBALS['var'];
// do something
}
In the second example, you pass the variable explicitly to the function, thus it is not taken from the global scope.
$var = 'something';
$GLOBALS['var'] = &$var;
function myFunc(&$var){
// do something
}
myFunc($var);
Both examples will reference the exact same variable, but using different mechanisms.
There is no technical difference at all between your two examples; they will always behave in an identical manner.
That leaves us looking for other types of differences, and there is a pretty significant code quality difference here: In the first version, looking at the call site will not tell you that the function depends on the global. In the second one it will (it's being passed in as a parameter). So the second form is, in my book at least, superior.
In addition, another difference (although one that does not apply to this example) is that the first form can only be used if your variable is in the global scope to begin with; the second will work everywhere.
You should also take into account that both these methods have an in/out argument. Normally you would not be writing code like this if it were just one argument (since you can return the out value instead) so it's interesting to consider the case where more than one arguments are being given. This is a pretty rare, and it can be argued that it's better to just return an array with multiple values rather than take multiple arguments by reference to make the code even easier to follow.
So in conclusion:
They do the same thing
If you are going to use one of them, prefer the second form (clearer, more flexible)
Consider using none of them and doing things otherwise if it doesn't require writing a substantial amount of additional code
One passes by value and one passes by reference:
By value:
$var = 'something';
function myFunc($var){
$var = 'hello';
}
echo $var; //something
By reference:
$var = 'something';
function myFunc(&$var){
$var = 'hello';
}
echo $var; //hello
For more information, the PHP manual has a page on passing by reference: http://php.net/manual/en/language.references.pass.php
In the case of globals, you are essentially pulling a variable from the global scope and using it inside of the function. It's like implicitly passing by reference.
This page, in particular the global section explains: http://us.php.net/manual/en/language.variables.scope.php
Please note that globals should typically be avoided. The short version of why is because they make knowing the state of a program difficult, and later changes can cause unexpected side effects.

PHP variable variables in {} symbols

I get the basics of variable variables, but I saw a syntax just know, which bogles my mind a bit.
$this->{$toShow}();
I don't really see what those {} symbols are doing there. Do they have any special meaning?
PHP's variable parser isn't greedy. The {} are used to indicate what should be considered part of a variable reference and what isn't. Consider this:
$arr = array();
$arr[3] = array();
$arr[3][4] = 'Hi there';
echo "$arr[3][4]";
Notice the double quotes. You'd expect this to output Hi there, but you actually end up seeing Array[4]. This is due to the non-greediness of the parser. It will check for only ONE level of array indexing while interpolating variables into the string, so what it really saw was this:
echo $arr[3], "[4]";
But, doing
echo "{$arr[3][4]}";
forces PHP to treat everything inside the braces as a variable reference, and you end up with the expected Hi there.
They tell the parser, where a variable name starts and ends. In this particular case it might not be needed, but consider this example:
$this->$toShow[0]
What should the parser do? Is $toShow an array or $this->$toShow ? In this case, the variable is resolved first and the array index is applied to the resulting property.
So if you actually want to access $toShow[0], you have to write:
$this->{$toShow[0]}
These curly braces can be used to use expressions to specify the variable identifier instead of just a variable’s value:
$var = 'foo';
echo ${$var.'bar'}; // echoes the value of $foobar
echo $$var.'bar'; // echoes the value of $foo concatenated with "bar"
$this->{$toShow}();
Break it down as below:
First this is a object oriented programming style as you got to see $this and ->. Second, {$toShow}() is a method(function) as you can see the () brackets.
So now {$toShow}() should somehow be parsed to a name like 'compute()'. And, $toShow is just a variable which might hold a possible function name. But the question remains, why is {} used around.
The reason is {} brackets substitues the value in the place. To clarify,
$toShow="compute";
so,
{$toShow}(); //is equivalent to compute();
but this is not true:
$toShow(); //this is wrong as a variablename is not a legal function name

Categories