For example, if I do this:
function bar(&$var)
{
$foo = function() use ($var)
{
$var++;
};
$foo();
}
$my_var = 0;
bar($my_var);
Will $my_var
be modified? If not, how do I get this to work without adding a parameter to $foo
?
Introduction. In PHP, arguments to a function can be passed by value or passed by reference. By default, values of actual arguments are passed by value to formal arguments which become local variables inside the function. Hence, modification to these variables doesn't change value of actual argument variable.
Pass by reference: When variables are passed by reference, use & (ampersand) symbol need to be added before variable argument. For example: function( &$x ).
A closure is a separate namespace, normally, you can not access variables defined outside of this namespace. There comes the use keyword: use allows you to access (use) the succeeding variables inside the closure.
With regards to your first question, the array is passed by reference UNLESS it is modified within the method / function you're calling. If you attempt to modify the array within the method / function, a copy of it is made first, and then only the copy is modified.
No, they are not passed by reference - the use
follows a similar notation like the function's parameters.
As written you achieve that by defining the use
as pass-by-reference:
$foo = function() use (&$var)
It's also possible to create recursion this way:
$func = NULL; $func = function () use (&$func) { $func(); }
NOTE: The following old excerpt of the answer (Jun 2012) was written for PHP < 7.0. As since 7.0 (Dec 2015) the semantics of
debug_zval_dump()
changed (different zval handling) therefcount(?)
output of it differs nowadays and are not that much saying any longer (integers don't have a refcount any longer).Validation via the output by not displaying
$my_var
changed (from0
) still works though (behaviour).
You can validate that on your own with the help of the debug_zval_dump
function (Demo):
function bar(&$var) { $foo = function() use ($var) { debug_zval_dump($var); $var++; }; $foo(); }; $my_var = 0; bar($my_var); echo $my_var;
Output:
long(0) refcount(3) 0
A full-through-all-scopes-working reference would have a refcount of 1.
Closures are, almost by definition, closed by value, not by reference. You may "use by reference" by adding an &
in the argument list:
function() use (&$var)
This can be seen in example 3 in the anonymous functions manual page.
No, they are not passed by reference.
function foo(&$var)
{
$foo = function() use ($var)
{
$var++;
};
$foo();
}
$my_var = 0;
foo($my_var);
echo $my_var; // displays 0
function bar(&$var)
{
$foo = function() use (&$var)
{
$var++;
};
$foo();
}
$my_var = 0;
bar($my_var);
echo $my_var; // displays 1
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With