Please see this code:
function addCounter(&$userInfoArray) {
$userInfoArray['counter']++;
return $userInfoArray['counter'];
}
$userInfoArray = array('id' => 'foo', 'name' => 'fooName', 'counter' => 10);
$nowCounter = addCounter($userInfoArray);
echo($userInfoArray['counter']);
This will show 11.
But! If you remove "&"operator in the function parameter, the result will be 10.
What's going on?
The & operator tells PHP not to copy the array when passing it to the function. Instead, a reference to the array is passed into the function, thus the function modifies the original array instead of a copy.
Just look at this minimal example:
<?php
function foo($a) { $a++; }
function bar(&$a) { $a++; }
$x = 1;
foo($x);
echo "$x\n";
bar($x);
echo "$x\n";
?>
Here, the output is:
1
2
– the call to foo didn’t modify $x. The call to bar, on the other hand, did.
Here the & character means that the variable is passed by reference, instead of by value. The difference between the two is that if you pass by reference, any changes made to the variable are made to the original also.
function do_a_thing_v ($a) {
$a = $a + 1;
}
$x = 5;
do_a_thing_v($x);
echo $x; // echoes 5
function do_a_thing_r (&$a) {
$a = $a + 1;
}
$x = 5;
do_a_thing_v($x);
echo $x; // echoes 6
When using the ampersand prior to a variable in a function call, it associates with the original variable itself. With that, the code you posted is saying that it will add 1 to the counter of the original array. Without the ampersand, it takes a copy of the data and adds to it, then returns the new counter of 11. The old array still remains intact at 10 and the new counter variable returned turns into 11.
http://www.phpreferencebook.com/samples/php-pass-by-reference/
is a good example.
Maybe I can add to the other answers that, if it is an object, then it is not "the object passed as value", but it is "the object's reference is passed as a value" (although I am asking what the difference is between "the object is passed by reference" vs "the object's reference is passed by value" in the comments). An array is passed by value by default.
Information: Objects and references
Example:
class Foo {
public $a = 10;
}
function add($obj) {
$obj->a++;
}
$foo = new Foo();
echo $foo->a, "\n";
add($foo);
echo $foo->a, "\n";
Result:
$ php try.php
10
11
Related
According to PHP documentation, a variable passed in ::send() method of generator class is assigned to yield keyword.
it makes sense in following statement :
$v = yield;
But what about the statements like :
$v = yield $a;
yield keyword is already assigned and it shall return the variable passed into. Then what does $a do?
I've tried to figure this out and searched many posts and questions but none of them explain this.
Answering by myself...
$v = yield $a;
meaning, first yield $a just as generally it does, then assign a variable passed by send() method to $v.
Still can't get clear explanation. But I think this is somewhat an answer of this matter.
Using send() will define $v, so if you use $v = yield $a; and before the iteration, you sent a value with send() it will yield the value which you sent it.
It can be hard to get your head around so here is an example, which creates two parts, the foreach iterator which loops over the generator and then on iteration 10 it sends a stop to the while loop. Then using getReturn gets the last value of the yield, like your $v in $v = yield $a;
<?php
$engine = function($callback) {
$i = 0;
while (true) {
$state = (yield $callback($i++));
if ($state == 'stop') {
return $i;
}
}
};
$generator = $engine(function($i) {
return $i;
});
foreach ($generator as $value) {
echo "{$generator->key()} = {$value}\n";
if ($generator->key() == 10) {
$generator->send('stop');
}
}
echo 'Stopped on: '.$generator->getReturn();
https://3v4l.org/dY8rV
Result:
0 = 0
1 = 1
2 = 2
3 = 3
4 = 4
5 = 5
6 = 6
7 = 7
8 = 8
9 = 9
10 = 10
Stopped on: 11
The yield keyword can be used for three things:
On its own, to return control temporarily to calling code. This is the basis of all the other uses.
With a value after (yield $foo), to pass a variable to calling code.
With an assignment before ($bar = yield), to receive a variable from calling code.
These are sort of similar to how you can use a function call:
On its own, like doSomething(), to pass control temporarily to the definition of doSomething.
With a parameter, like doSomething($foo), to pass a variable to the function.
With an assignment before, like $var = doSomething(), to receive a variable from the function.
You are hopefully quite familiar with writing $bar = doSomething($foo); to pass $foo to a function, and get $bar out afterwards. $bar = yield $foo is similar, but the value is passed "out" to the calling code, and the new value received back from that calling code afterwards.
$foo and $bar are not connected in any way, they are just the input and output of that particular yield. In the calling code, the $foo part of yield $foo or $bar = yield $foo can be accessed by calling ->next() or ->current() or getting the value in a foreach. The calling code then calls ->send() with some value which becomes the $bar in $bar = yield or $bar = yield $foo.
This question already has answers here:
PHP param by ref => assign to ref = NULL
(1 answer)
PHP's assignment by reference is not working as expected
(7 answers)
Closed 8 years ago.
Here is the simplified version of code that might be revealing a PHP bug
class AClass
{
public static $prop = "Hi";
}
function assignRef (&$ref)
{
$ref = &AClass::$prop;
echo "inside assignRef: $ref\n";
}
$ref = "Hello";
assignRef($ref);
echo "outside: $ref\n";
This prints out
inside assignRef: Hi
outside: Hello
Shouldn't $ref had been assigned by reference to $prop static variable of the AClass class and become "Hi" not just inside assignRef function but also outside of it?
The class in your example is irrelevant, simplified version that produces the same output:
function assignRef (&$ref)
{
$prop = 'Hi';
$ref = &$prop;
echo "inside assignRef: $ref\n";
}
$ref = "Hello";
assignRef($ref);
echo "outside: $ref\n";
What is happening is that when assigning by reference inside the function ($ref = &$prop;) you are just changing what one variable is pointing to, not changing the value of what it was originally pointing to nor changing any other references to that original value.
You effectively have two variables called $ref in this example - one inside the function, and one outside the function. You are changing what the variable inside the function points to, leaving the other variable pointing to the original (unchanged) value.
Consider the following code:
$a = 'a';
$b = 'b';
$c = 'c';
$a = &$b;
$b = &$c;
echo "$a / $b / $c";
This results in output of b / c / c, rather than what you might expect c / c / c. This happens for the same reason - assignment by reference does not affect the value originally referenced nor change any other references, meaning any other variables pointing to the original value are unchanged.
If you want to change the value, rather than creating a new reference to another value, you must use normal assignment (=). Alternatively, you could change all references.
I want to increase $x by 1:
$x = 1;
function addOne($x) {
$x++;
return $x;
}
$x = addOne($x);
Is there a way to do this with references, so I don't need to return $x, I can just write addOne($x)?
This is what you're looking for, a by-ref parameter indicated by &.
$x = 1;
function addOne(&$x) {
$x++;
}
addOne($x);
Some notes:
By-ref parameters require that the value passed in not be a literal. Given my example above, addOne(5) would throw a fatal exception
References are not needed for objects (including stdClass objects), as all objects are passed by reference as of PHP 5.
References ARE needed for arrays, as arrays in PHP are not treated as objects
If you want a return value of a function passed by reference, you would indicate the reference on the function name (e.g. function &foo()).
More info on references: http://php.net/manual/en/language.references.php
$x = 1;
function addOne(&$x) {
$x++;
}
addOne($x);
The & sign shows that it takes the parameter by reference. So it increments $x in the function and it will also affect the $x variable in the calling scope.
See also: http://php.net/references for a quick overview about them.
I have a simple question here. Is there a difference between passing a variable by reference in a function parameter like:
function do_stuff(&$a)
{
// do stuff here...
}
and do it inside the function like:
function do_stuff($a)
{
$var = &$a;
// do stuff here...
}
What are the differences (if any) between using these two?. Also, can anybody give me a good tutorial that explains passing by reference? I can't seem to grasp this concept 100%.
Thank you
Here's a set of examples so you can see what happens with each of your questions.
I also added a third function which combines both of your questions because it will also produce a different result.
function do_stuff(&$a)
{
$a = 5;
}
function do_stuff2($a)
{
$var = &$a;
$var = 3;
}
function do_stuff3(&$a)
{
$var = &$a;
$var = 3;
}
$a = 2;
do_stuff($a);
echo $a;
echo '<br />';
$a = 2;
do_stuff2($a);
echo $a;
echo '<br />';
$a = 2;
do_stuff3($a);
echo $a;
echo '<br />';
They're not at all equivalent. In the second version, you're creating a reference to an undefined variable $a, causing $var to point to that same null value. Anything you do to $var and $a inside the second version will not affect anything outside of the function.
In the first version, if you change $a inside the function, the new value will be present outside after the function returns.
In your first example, if you modify $a inside the function in any way, the original value outside the function will be modified as well.
In your second example, whatever you do to $a or its reference $var will not modify the original value outside the function.
In the second function, the $a passed into the function is a copy of the argument passed in, (unless $a is an object), so you are making a $var a reference to the $a inside the function but it will still be separate from the variable passed to the function.
Assuming you are using a recent version of PHP, objects are automatically passed by reference too, so that could make a difference.
(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.