6

I have:

function outside( $limit ) {

$tally = 0;

    return function() use ( $limit, &$tally ) {
        $tally++;

        if( $tally > $limit ) {
            echo "limit has been exceeded";
        }
    };
}

$inside = outside( 2 );
$inside();
$inside();
$inside();

Outputs: limit has been exceeded

My understanding:

  1. on $inside = outside( 2 ); this returns the anonymous function and assigns it to the variable$inside. The anonymous function uses the value of $limit (2) and $tally (0).

  2. function $inside() is called. This increments $tally to 1 The value is remembered somehow and so is $limit. What is the purpose of the ampersand before $tally? I know it's used to create references but in this context it confuses me. How can this closure remember the value of $limit?

Any references to official documentation would help!

Robert
  • 10,126
  • 19
  • 78
  • 130
  • Now there's some interesting code! Not seen that stuff in a while. – matrixdevuk Oct 07 '14 at 02:01
  • 2
    I actually protest that this question is a duplicate. While it is very similar, this question focuses more about the variable being passed by reference rather than the usage of the `use` keyword itself. – Scopey Oct 07 '14 at 02:13

2 Answers2

7

Anonymous functions are actually Closure objects in php. If you add var_dump($invoke) to your code, you'll see this:

object(Closure)#1 (1) {
  ["static"]=>
  array(2) {
    ["limit"]=>
    int(2)
    ["tally"]=>
    int(0)
  }
}

use'd variables are stored in the static array in the closure object. When you invoke the closure, these variables are passed to the function, just like normal arguments. Therefore, if you don't use a reference, they will be passed by copying and any changes to them in the function will have no effect.

georg
  • 211,518
  • 52
  • 313
  • 390
  • How does the value of $limit persist in subsequent calls, when its not declared as a reference? – Robert Oct 07 '14 at 02:48
  • Oh ok so since its a static priperty of the closure object the value persist throughout subsequent calls? I think i undersrand better now. – Robert Oct 07 '14 at 02:57
4

The & means you pass the argument by reference and not value. This means you can change the variable inside the function, and it will be remembered outside - not just in that function.

By assigning the function to $inside, you are effectively keeping the reference to the variable intact, so it will be remembered from call to call.

See PHP: Passing by Reference

worldofjr
  • 3,868
  • 8
  • 37
  • 49
  • I thought inside functions the keyword, 'static' was used for 'remembering' purposes, not the ampersand for remembering – Robert Oct 07 '14 at 02:12
  • Yes, that would work, but the `&` means you can pass the variable from outside the function, such as a reference to an object, or a global value (which isn't the same variable each time), ie it has to be set to a variable outside the function. – worldofjr Oct 07 '14 at 02:16
  • You could also pass a variable by value (without the `&`) and then return that value from the function and set it to the same variable. That would be functionally the same. But if you needed a function to change two variables (for example) then this becomes more complicated. – worldofjr Oct 07 '14 at 02:20