php variable parsing in double quoted strings - php

while reading about variable parsing in double quoted strings in the php manual I came across 2 examples which are confusing to me. An example of how this works with some code would help greatly. Here is the code from the manual:
echo "This works too: {$obj->values[3]->name}";
echo "This is the value of the var named $name: {${$name}}";
echo "This is the value of the var named by the return value of getName(): {${getName()}}";
What exactly do these mean? I know that $obj is an object. I just don't know what would've been the precursor code of these examples. Any help would be useful.

Let's use the 3 examples from the manual you gave.
We can provide these variables a name and look at the output to see what they do.
$obj->values[3]->name = "Object Value";
$name = "variable";
$variable = "Variable Value"; // You'll see why we need to define this in a minute
$function = "Function Value";
function getName() {
return "function";
}
I imagine you're already seeing where this is going but let's see what this mean for the statements you posted:
echo "This works too: {$obj->values[3]->name}"; // This works too: Object Value
echo "This is the value of the var named $name: {${$name}}"; // This is the value of the var named $name: Variable Value
echo "This is the value of the var named by the return value of getName(): {${getName()}}"; // This is the value of the var named by the return value of getName(): Function Value
In the first case, it replaces the object value with "Object Value."
In the second $name gets interpreted as "variable", which means {${$name}} gets interpreted as the value of $variable, which is "Variable Value."
The same principle applies to the return value of the function.

Here follows the examples you posted,
When you use {}you make sure the entire path of the object gets evaluated. If you remove them it will only evaluate $obj->values which returns Array.
$obj->values[3] = "Name";
echo "This works too: {$obj->values[3]}"."\n"; // CORRECT: This works too: Name
echo "This works too: $obj->values[3]"."\n\n"; // ERROR: This works too: Array[3]
In the first two examples $name is evaluated first, and you will be left with {$mike}. Since you have the curly braces outside the new variable name, this too will be evaluated, and will translate to the string Michael instead. In the last example you will be left with $mike.
$name = "mike";
$mike = "Michael";
echo "This is the value of the var named $name: {${$name}}"."\n"; // This is the value of the var named mike: Michael
echo "This is the value of the var named $name: {$$name}"."\n"; // This is the value of the var named mike: Michael
echo "This is the value of the var named $name: $$name"."\n\n"; // This is the value of the var named mike: $mike
This example is similar to the one above, but instead of using the variable $name, a function is used instead. If you do not have the curly braces {} around the function (example #2), but around $getName(), PHP will try to to access the function $getName, which is not a legal function name.
The last example $getName() will fetch the value of the variable $getName and the () will be left alone. So if you would have $getName = "Heya";, it would become Heya().
function getName() { return "mike"; }
echo "This is the value of the var named by the return value of getName(): {${getName()}}"; // This is the value of the var named by the return value of getName(): Michael
echo "This is the value of the var named by the return value of getName(): {$getName()}"; // Fatal error: Function name must be a string
echo "This is the value of the var named by the return value of getName(): $getName()"; // This is the value of the var named by the return value of getName(): ()

Related

Purpose of complex (curly) syntax outside a string representation

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.

What is the difference between "{$var1}someString" and "$var1someString"?

I can make out the difference between
echo "{$var1}someString" // here the variable is $var1
echo "$var1someString" // here the variable is $var1someString
The question is why to use {}? It works only with {}. It does not work with (). What is so special about { }?
The curly braces {} are used in that way to identify variables within strings:
echo "{$var1}someString"
If you look at:
echo "$var1someString"
PHP can't possibly determine that you wanted to echo $var1, it's going to take all of it as the variable name.
You could concatenate your variables instead:
echo $var1 . "someString"
It doesn't work for () simply because the PHP designers choose {}.
you expained it yourself. thats simply the syntax php uses for this - nothing more. to quote the documentation:
Complex (curly) 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 {$
According to the documentation of string, the curly part is called complex syntax. It basically allows you to use complex expressions inside string.
Example from the documentation:
<?php
// Show all errors
error_reporting(E_ALL);
$great = 'fantastic';
// Won't work, outputs: This is { fantastic}
echo "This is { $great}";
// Works, outputs: This is fantastic
echo "This is {$great}";
echo "This is ${great}";
// Works
echo "This square is {$square->width}00 centimeters broad.";
// Works, quoted keys only work using the curly brace syntax
echo "This works: {$arr['key']}";
// Works
echo "This works: {$arr[4][3]}";
// This is wrong for the same reason as $foo[bar] is wrong outside a string.
// In other words, it will still work, but only because PHP first looks for a
// constant named foo; an error of level E_NOTICE (undefined constant) will be
// thrown.
echo "This is wrong: {$arr[foo][3]}";
// Works. When using multi-dimensional arrays, always use braces around arrays
// when inside of strings
echo "This works: {$arr['foo'][3]}";
// Works.
echo "This works: " . $arr['foo'][3];
echo "This works too: {$obj->values[3]->name}";
echo "This is the value of the var named $name: {${$name}}";
echo "This is the value of the var named by the return value of getName(): {${getName()}}";
echo "This is the value of the var named by the return value of \$object->getName(): {${$object->getName()}}";
// Won't work, outputs: This is the return value of getName(): {getName()}
echo "This is the return value of getName(): {getName()}";
?>
Here {} define that variable within these are not a simple string so php pic up that variable value instead of assuming that as a simple string.

difference between call by value and call by reference in php and also $$ means?

(1) I want to know what is the difference between call by value and call by reference in php. PHP works on call by value or call by reference?
(2) And also i want to know that do you mean by $$ sign in php
For example:-
$a = 'name';
$$a = "Paul";
echo $name;
output is Paul
As above example what do u mean by $$ on PHP.
$$a = b; in PHP means "take the value of $a, and set the variable whose name is that value to equal b".
In other words:
$foo = "bar";
$$foo = "baz";
echo $bar; // outputs 'baz'
But yeah, take a look at the PHP symbol reference.
As for call by value/reference - the primary difference between the two is whether or not you're able to modify the original items that were used to call the function. See:
function increment_value($y) {
$y++;
echo $y;
}
function increment_reference(&$y) {
$y++;
echo $y;
}
$x = 1;
increment_value($x); // prints '2'
echo $x; // prints '1'
increment_reference($x); // prints '2'
echo $x; // prints '2'
Notice how the value of $x isn't changed by increment_value(), but is changed by increment_reference().
As demonstrated here, whether call-by-value or call-by-reference is used depends on the definition of the function being called; the default when declaring your own functions is call-by-value (but you can specify call-by-reference via the & sigil).
Let's define a function:
function f($a) {
$a++;
echo "inside function: " . $a;
}
Now let's try calling it by value(normally we do this):
$x = 1;
f($x);
echo "outside function: " . $x;
//inside function: 2
//outside function: 1
Now let's re-define the function to pass variable by reference:
function f(&$a) {
$a++;
echo "inside function: " . $a;
}
and calling it again.
$x = 1;
f($x);
echo "outside function: " . $x;
//inside function: 2
//outside function: 2
You can pass a variable by reference to a function so the function can modify the variable.
More info here.
Call by value: Passing the variable value directly and it will not affect any global variable.
Call by reference: Passing the address of a variable and it will affect the variable.
It means $($a), so its the same as $name (Since $a = 'name'). More explanation here What does $$ (dollar dollar or double dollar) mean in PHP?
Call by value means passing the value directly to a function. The called function uses the value in a local variable; any changes to it do not affect the source variable.
Call by reference means passing the address of a variable where the actual value is stored. The called function uses the value stored in the passed address; any changes to it do affect the source variable.

Php user defined functions, (im new need help)

I understand I can define a function like this:
<?php
function say_hello() {
echo "hello world!";
}
say_hello();
?>
...and then reuse this function elsewhere as many times as I need by just calling the function by name.
What I don't understand is "passing data to arguments within the function". I'm confused what's meant by within.
From one of the lessons I've been studying, I have this function:
<?php
function say_helloTWO( $word ) {
echo " {$word} hello world a second time ";
}
say_helloTWO( "my name is mike");
?>
This prints on screen
my name is mike hello world a second time
When I test the function with the argument "my name is mike", it prints to screen, but I don't understand how this works. The variable $word wasn't declared anywhere, so, if I take out the "$word" from the echo, then only "hello world a second time" shows without the my name is mike.
This leads me to believe that somewhere within this block of code, $word was defined, is that right?
In your second function $word is being declared in the function definition function say_helloTWO( $word ).
So the function is expecting 1 parameter, which will be assigned to the variable $word for use within that function.
So when you call say_helloTWO( "my name is mike"); you are passing 1 parameter ("my name is mike") to the function say_helloTWO. This 1 parameter gets assigned to the 1st variable in the function definition, and is therefore available within the function as $word.
Make sense?
In this case the function definition is said to take one arguments.
function say_helloTWO( $word ) // $word is the name of this argument
When you call the function in your code the first thing you pass in the brackets will be passed as the first argument. Therefore in your example the string "my name is mike" is being passed into the function and assigned to the variable $word.
If we expand on this and have a function that takes two arguments like this
function say_helloTHREE( $word, $secondArg )
Then this function would now expect two arguments to be passed into it. The first argument would be assigned to $word and the second argument will be assigned to $secondArg.
You need to read this: http://php.net/manual/en/functions.arguments.php
<?php
function say_helloTWO( $word ) {
echo " {$word} hello world a second time ";
}
say_helloTWO( "my name is mike");
?>
In this code, the 'declaration' of the variable $word is made within the function declaration. As you see on this line function say_helloTWO( $word ) { you can find $word on that line. This is enough for the PHP parser to know that for the first agument of the is to be known as word within this functions scope. The function then echos out that variable on a later line echo " {$word} hello world a second time "; where again $word is present prints out both what you set as the value of the first argument on this line say_helloTWO( "my name is mike");.
Good question.
This counts as a valid declaration. It's defined when supplied as an argument when the function is called.
<?php
function my_name_is ($name) {
echo "Hello, my name is " . $name;
}
my_name_is('mike');
// returns 'Hello, my name is mike'
?>
Because, when calling the function, they supply 'mike' as an argument, $name becomes 'mike'. It's just how functions work.
EDIT:
It's a special rule. $name doesn't need to be declared because it will be defined when the function is called. PHP understands this. If you don't supply an argument, it's still defined, it's just empty... I believe.
It's passed as a parameter. So it was sorta already declared inside the parenthesis
If you did:
function say_helloTWO( $word1, $word2, $word3 )
and called:
say_helloTWO("a", "b", "c");
That would call say_helloTWO and set the variable $word1 to "a", $word2 to "b" and $word3 to "c"
Those three variables are defined in say_helloTWO for the duration that that function is running.
To give a practical example, say you had a function to solve quadratic equations, it would look like
function quadratic( $a, $b, $c ) {
$x = ( $b + sqrt( (b*b - 4*a*c) ) )/ 2*a;
return $x;
}
Then, instead of rewriting the code to solve a quadratic each time, you could call it like this:
$y = quadratic (1, 2, 3);
This would set $a to 1, $b to 2 and $c to 3, and store the result in $y.
You can consider the quadratic function to be a sort of "mini-program", independent of the rest of your program, $a, $b and $c only apply within the quadratic function.
this leads me to believe that somewhere within this block of code, $word was defined, is that right?
No, $word is not defined within the function block, it is given the value of "my name is mike" when you mane the call.
In other words, $word is defined when you call the function:
/* here you are defining word to "my name is mike" */
say_helloTWO( "my name is mike");
/* here you are defining word to "my name is jack"*/
say_helloTWO( "my name is jack");
If the above still don't make much sense to you then I think you may need to go back to the basic and study what is a function in programming world.

Curly braces in string in PHP

What is the meaning of { } (curly braces) in string literals in PHP?
This is the complex (curly) syntax for string interpolation. From the manual:
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 {$. Some examples to make it clear:
<?php
// Show all errors
error_reporting(E_ALL);
$great = 'fantastic';
// Won't work, outputs: This is { fantastic}
echo "This is { $great}";
// Works, outputs: This is fantastic
echo "This is {$great}";
echo "This is ${great}";
// Works
echo "This square is {$square->width}00 centimeters broad.";
// Works, quoted keys only work using the curly brace syntax
echo "This works: {$arr['key']}";
// Works
echo "This works: {$arr[4][3]}";
// This is wrong for the same reason as $foo[bar] is wrong outside a string.
// In other words, it will still work, but only because PHP first looks for a
// constant named foo; an error of level E_NOTICE (undefined constant) will be
// thrown.
echo "This is wrong: {$arr[foo][3]}";
// Works. When using multi-dimensional arrays, always use braces around arrays
// when inside of strings
echo "This works: {$arr['foo'][3]}";
// Works.
echo "This works: " . $arr['foo'][3];
echo "This works too: {$obj->values[3]->name}";
echo "This is the value of the var named $name: {${$name}}";
echo "This is the value of the var named by the return value of getName(): {${getName()}}";
echo "This is the value of the var named by the return value of \$object->getName(): {${$object->getName()}}";
// Won't work, outputs: This is the return value of getName(): {getName()}
echo "This is the return value of getName(): {getName()}";
?>
Often, this syntax is unnecessary. For example, this:
$a = 'abcd';
$out = "$a $a"; // "abcd abcd";
behaves exactly the same as this:
$out = "{$a} {$a}"; // same
So the curly braces are unnecessary. But this:
$out = "$aefgh";
will, depending on your error level, either not work or produce an error because there's no variable named $aefgh, so you need to do:
$out = "${a}efgh"; // or
$out = "{$a}efgh";
As for me, curly braces serve as a substitution for concatenation, they are quicker to type and code looks cleaner. Remember to use double quotes (" ") as their content is parsed by PHP, because in single quotes (' ') you'll get the literal name of variable provided:
<?php
$a = '12345';
// This works:
echo "qwe{$a}rty"; // qwe12345rty, using braces
echo "qwe" . $a . "rty"; // qwe12345rty, concatenation used
// Does not work:
echo 'qwe{$a}rty'; // qwe{$a}rty, single quotes are not parsed
echo "qwe$arty"; // qwe, because $a became $arty, which is undefined
?>
Example:
$number = 4;
print "You have the {$number}th edition book";
//output: "You have the 4th edition book";
Without curly braces PHP would try to find a variable named $numberth, that doesn't exist!
I've also found it useful to access object attributes where the attribute names vary by some iterator. For example, I have used the pattern below for a set of time periods: hour, day, month.
$periods=array('hour', 'day', 'month');
foreach ($periods as $period)
{
$this->{'value_'.$period}=1;
}
This same pattern can also be used to access class methods. Just build up the method name in the same manner, using strings and string variables.
You could easily argue to just use an array for the value storage by period. If this application were PHP only, I would agree. I use this pattern when the class attributes map to fields in a database table. While it is possible to store arrays in a database using serialization, it is inefficient, and pointless if the individual fields must be indexed. I often add an array of the field names, keyed by the iterator, for the best of both worlds.
class timevalues
{
// Database table values:
public $value_hour; // maps to values.value_hour
public $value_day; // maps to values.value_day
public $value_month; // maps to values.value_month
public $values=array();
public function __construct()
{
$this->value_hour=0;
$this->value_day=0;
$this->value_month=0;
$this->values=array(
'hour'=>$this->value_hour,
'day'=>$this->value_day,
'month'=>$this->value_month,
);
}
}

Categories