1

The following code is a slightly modified version of an example from

PHP Manual -> Language Reference -> Functions -> Anonymous functions.

The example mentions, but doesn't explain, why you cannot pass a PHP object by value to the argument list after the use keyword in a function. In paricular, why isn't the object passed by value in the use parameter list as in the following code copied inside the $broken anonymous function just like can be done with scalar values?

Here is the code:

class MyClass {

  function doSomething() { echo "HELLO WORLD\n"; }

}

$myInstance = null;

$broken = function() use ($myInstance) {
    if(!empty($myInstance)) $myInstance->doSomething();
    else echo "\$myInstance is empty.\n";
    var_dump($myInstance); // NULL
};

$working = function() use (&$myInstance) {
    if(!empty($myInstance)) $myInstance->doSomething();
    else print "\$myInstance is empty.\n";
};

$myInstance = new MyClass();

$myInstance->doSomething();    // Outputs HELLO WORLD.
$broken();                     // Outputs $myInstance is empty. NULL
$working();                    // Outputs HELLO WORLD.

Thanks.


This is an update to my post following the reply I received from Valentin Rodygin. If the $myInstance = null; line is commented out I get the following error:

Notice: Undefined variable: myInstance in C:\xampp\htdocs\myexamples\use.php on line 11

Basically, when the parameter to the use keyword is passed by value it is copied at the time the function that makes use of the use keyword is defined, not when the function that makes use of the use keyword is called. The same is true for variables which are passed by reference, but since they are passed by reference, any later modification to such variable prior to invoking the function will make the updated value of such a variable available inside the function.

Thanks.

1

1 Answer 1

2

Let's take a closer look at your code.

$myInstance = null;
$broken = function() use ($myInstance) {
    if(!empty($myInstance)) $myInstance->doSomething();
    else echo "\$myInstance is empty.\n";
    var_dump($myInstance); // NULL
};

At this moment, you've already created a closure and passed there a copy of the variable and it's NULL.

$working = function() use (&$myInstance) {
    if(!empty($myInstance)) $myInstance->doSomething();
    else print "\$myInstance is empty.\n";
};

And here you passed a reference, so later, when you've instantiated $myInstance, it became accessible in the closure.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks. I've update my post to reflect the explanation you gave in your answer. Regards.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.