note 95994 deleted from functions.anonymous by danbrown

From: Date: Tue, 02 Feb 2010 16:00:19 +0000
Subject: note 95994 deleted from functions.anonymous by danbrown
References: 1  Groups: php.notes 
Request: Send a blank email to php-notes+get-165600@lists.php.net to get a copy of this message
Note Submitter: bishamon ---- Someone needs to rewrite the documentation for this section. An anonymous function IS NOT the same thing as a closure. Anonymous functions are needed to implement closures, but they're not the same thing. A closure is a function that has it's scope bound to another scope. Typically, the other scope is the local scope of another function. The closure then is a function that's nested inside another function but still has access to the "outer" function's variables. To put it another way, a closure is an anonymous function, but an anonymous function is not always a closure. Here's an example of how closures work: <?php function outer () { $var = 0; return function () use (&$var) { $var++; var_dump($var); }; } $inner = outer(); $inner(); // int 1 $inner(); // int 2 $inner(); // int 3 ?> Several things are happening here, so let's look at them: 1) The return value of outer() is a function. This is where the anonymous function comes into play. 2) The function returned by outer() has access to outer()'s variable $var through the use() clause. Furthermore, it can modify that variable since it is accessed as a reference. 3) The when outer() is called, the anonymous function it returns is stored in the variable $inner. Even though outer() is finished running, because a reference to the function defined inside it still exists, the variables (or state) of outer() is maintained. This is what creates the closure. As long as $inner exists, $var will also exist and be accessible by the function in $inner. 4) When $inner() is called, the code in the anonymous function executes. It still has access to the $var variable defined in outer(). A function can also return a closure through its parameters by using a reference. This allows you to return multiple closure functions from a function. Here's an example to show how powerful closures are: <?php function counter_factory(&$add, &$sub) { $var = 0; $add = function ($i = 1) use (&$var) { $var += $i; var_dump($var); }; $sub = function ($i = 1) use (&$var) { $var -= $i; var_dump($var); }; } counter_factory($x_up, $x_down); // a closure over $var is created counter_factory($y_up, $y_down); // a closure over a different $var is created // These work with the first closure $x_up(); // int 1 $x_up(3); // int 4 $x_down(2); // int 2 $x_up(); // int 3 // These work with the second closure $y_up(); // int 1 $y_down(2); // int -1 $y_up(); // int 0 // The statements above could be interleaved and still get the same results. ?> The magic that happens here is that each time counter_factory() is called, a new closure (a scope that includes $var and the two functions) is created. The returned functions have access to the $var where they were created. They then act as independent counters.

« previous php.notes (#165600) next »