PHP's Closure (Closure) is an anonymous function, introduced by PHP5.3.
The syntax of a closure is simple, and the key word to note is that only use,use are connected to closures and external variables.
$a function Use ($b) {}
A simple example is as follows:
function callback ( $fun $fun ();} $msg = "Hello, everyone" $fun = function () use ( $msg print "A closure use string value, MSG is: $msg . <br/>/n ";}; $msg = "Hello, everybody" callback ( $fun );
The result: This is a closure use string value, msg Is:hello, everyone. <BR/>/n
in the new open closure syntax for PHP, we used use to define variables outside the closure. Here we use the external variable $msg, after the definition, and then the value of the change, the closure is executed after the output is the original value. the value of the closure use is determined when the closure is created by the underlying type parameter passed as a pass-through value.
Small applications are as follows:
/** a counter generator using closures * Here is a reference to Python in the case of closures ... * We can consider this: * 1. Counter function each call, create a local variable $counter, initialized to 1. * 2. Then a closure is created, and the closure produces a reference to the local variable $counter. * 3. The function counter returns the created closure and destroys the local variable, but at this time there is a $counter reference to the closure, * It is not recycled, so we can understand that the closure returned by the function counter, carrying a free State * Variable. * 4. Since each call to counter creates separate $counter and closures, the returned closures are independent of each other. * 5. Executes the returned closure, and the Free State variable it carries is self-incremented and returned, resulting in a counter. * Conclusion: This function can be used to generate counters that are independent of each other. */ functioncounter () {$counter= 1; return function() Use(&$counter) {return $counter++;}; } $counter 1=counter (); $counter 2=counter (); Echo"Counter1:".$counter 1() . "<br/>/n"; Echo"Counter1:".$counter 1() . "<br/>/n"; Echo"Counter1:".$counter 1() . "<br/>/n"; Echo"Counter1:".$counter 1() . "<br/>/n"; Echo"Counter2:".$counter 2() . "<br/>/n"; Echo"Counter2:".$counter 2() . "<br/>/n"; Echo"Counter2:".$counter 2() . "<br/>/n"; Echo"Counter2:".$counter 2() . "<br/>/n"; ?>
The role of closures
1. Reduce the code of the Foreach Loop
such as the example cart in the handbook http://php.net/manual/en/functions.anonymous.php
<?PHP//a basic shopping cart, including some already added items and the quantity of each item. There is one way to calculate the total price of all the items in the shopping cart. The method uses a closure as the callback function. classcart{ConstPrice_butter = 1.00; ConstPrice_milk = 3.00; ConstPrice_eggs = 6.95; protected $products=Array(); Public functionAdd$product,$quantity) { $this->products[$product] =$quantity; } Public functionGetquantity ($product) { return isset($this->products[$product]) ?$this->products[$product] :FALSE; } Public functionGettotal ($tax) { $total= 0.00; $callback=function($quantity,$product) Use($tax, &$total) { $pricePerItem=constant(__class__. "::P rice_".Strtoupper($product)); $total+= ($pricePerItem*$quantity) * ($tax+ 1.0); }; //use a user-defined function to do callback processing for each element in the array Array_walk($this->products,$callback); return round($total, 2);; }} $my _cart=NewCart;//Add items to your shopping cart$my _cart->add (' Butter ', 1);$my _cart->add (' Milk ', 3);$my _cart->add (' Eggs ', 6); //Hit the total Price, which has a sales tax of 5%.Print $my _cart->gettotal (0.05). "\ n";//The result is 54.29?>
Here, if we transform the Gettotal function, we must use foreach.
2. Reduce the parameters of the function
functionhtml$code,$id="",$class=""){if($id!== "")$id= "id = \"$id\"" ;$class= ($class!== "")? "Class =\"$class\ ">": ">";$open= "<$code $id$class";$close= "</$code> ";return function($inner= "") Use($open,$close){return"$open $inner$close"; };}
If you use the usual method, we will put inner into the HTML function parameters, so that neither code reading nor use is as good as using closures.
3. Lifting the recursive function
<?PHP$fib=function($n) Use(&$fib) { if($n= = 0 | |$n= = 1)return1; return $fib($n-1) +$fib($n-2);}; Echo $fib(2). "\ n";//2$lie=$fib;$fib=function(){ die(' Error ');};//rewrite $FIB variableEcho $lie(5);//error because $FIB is referenced by closure
Note that the use of the & in the above title is not used, & error will occur fib(n-1) No function is found (the type of FIB is not previously defined)
So when you want to use closures to remove the loop function, you need to use the
<? PHP $recursive function Use (&$recursive) {// The function is now available as $recursive}
Such a form.
4. Delay Binding
If you need to delay the binding of a variable inside a use, you need a reference, or you will make a copy of it when you define it.
<?PHP$result= 0; $one=function(){ Var_dump($result);}; $two=function() Use($result){ Var_dump($result);}; $three=function() Use(&$result){ Var_dump($result);}; $result++; $one();//outputs NULL: $result is not in scope$two();//outputs int (0): $result was copied$three();//outputs int (1)
The use of references and non-use of references represents the assignment of a call, or the assignment of a value at the time of declaration
PHP Learning--php Closures