php的闭包函数 function()use(){}

本文介绍了PHP中的闭包概念,展示了如何使用匿名函数简化代码,并通过具体示例解释了闭包的优点,包括减少循环代码、减少函数参数、解除递归函数以及理解延迟绑定。

http://www.jb51.net/article/36269.htm

一.介绍

定义:将匿名函数在普通函数中当做参数传入,也可以被返回。这就实现了一个简单的闭包。use是为了连接闭包和外界变量(也就是为了可以引用函数外的变量,因为匿名函数不可以使用函数外的变量)

       php的闭包(Closure)也就是匿名函数。是PHP5.3引入的 

二.详解


闭包的几个优点:

1 减少foreach的循环的代码

比如手册http://php.net/manual/en/functions.anonymous.php 中的例子Cart

[php]  view plain  copy
 print ?
  1. <?php  
  2. // 一个基本的购物车,包括一些已经添加的商品和每种商品的数量。  
  3. // 其中有一个方法用来计算购物车中所有商品的总价格。该方法使用了一个closure作为回调函数。  
  4. class Cart  
  5. {  
  6.     const PRICE_BUTTER  = 1.00;  
  7.     const PRICE_MILK    = 3.00;  
  8.     const PRICE_EGGS    = 6.95;  
  9.    
  10.     protected   $products =array();  
  11.        
  12.     public function add($product,$quantity)  
  13.     {  
  14.         $this->products[$product] = $quantity;  
  15.     }  
  16.        
  17.     public function getQuantity($product)  
  18.     {  
  19.         return isset($this->products[$product]) ? $this->products[$product] :  
  20.                FALSE;  
  21.     }  
  22.        
  23.     public function getTotal($tax)  
  24.     {  
  25.         $total = 0.00;  
  26.            
  27.         $callback =  
  28.             function ($quantity,$product)use ($tax, &$total)  
  29.             {  
  30.                 $pricePerItem = constant(__CLASS__ ."::PRICE_" .  
  31.                     strtoupper($product));  
  32.                 $total += ($pricePerItem *$quantity) * ($tax + 1.0);  
  33.             };  
  34.            
  35.         array_walk($this->products,$callback);  
  36.         return round($total, 2);;  
  37.     }  
  38. }  
  39.    
  40. $my_cart =new Cart;  
  41.    
  42. // 往购物车里添加条目  
  43. $my_cart->add('butter', 1);  
  44. $my_cart->add('milk', 3);  
  45. $my_cart->add('eggs', 6);  
  46.    
  47. // 打出出总价格,其中有 5% 的销售税.  
  48. print $my_cart->getTotal(0.05) . "\n";  
  49. // The result is 54.29  
  50. ?>  


这里如果我们改造getTotal函数必然要使用到foreach 

2 减少函数的参数

[php]  view plain  copy
 print ?
  1. function html ($code ,$id="",$class=""){  
  2.    
  3. if ($id !=="")$id =" id = \"$id\"" ;  
  4.    
  5. $class = ($class !=="")?" class =\"$class\"":">";  
  6.    
  7. $open ="<$code$id$class";  
  8.    
  9. $close ="</$code>";  
  10.    
  11. return function ($inner ="")use ($open,$close){  
  12.    
  13. return "$open$inner$close";};  
  14.    
  15. }  
  16. 如果是使用平时的方法,我们会把inner放到html函数参数中,这样不管是代码阅读还是使用都不如使用闭包  


3 解除递归函数

[php]  view plain  copy
 print ?
  1. <?php  
  2.     $fib =function($n)use(&$fib) {  
  3.         if($n == 0 || $n == 1) return 1;  
  4.         return $fib($n - 1) + $fib($n - 2);  
  5.     };  
  6.    
  7.    echo $fib(2) . "\n";// 2  
  8.    $lie =$fib;  
  9.    $fib =function(){die('error');};//rewrite $fib variable   
  10.    echo $lie(5);// error   because $fib is referenced by closure  


注意上题中的use使用了&,这里不使用&会出现错误fib(fib(n-1)是找不到function的(前面没有定义fib的类型)

所以想使用闭包解除循环函数的时候就需要使用

[php]  view plain  copy
 print ?
  1. <?php  
  2. $recursive =function ()use (&$recursive){  
  3. // The function is now available as $recursive  
  4. }  


这样的形式

 

4 关于延迟绑定

如果你需要延迟绑定use里面的变量,你就需要使用引用,否则在定义的时候就会做一份拷贝放到use中

[php]  view plain  copy
 print ?
  1. <?php  
  2. $result = 0;  
  3.    
  4. $one =function()  
  5. { var_dump($result); };  
  6.    
  7. $two =function()use ($result)  
  8. { var_dump($result); };  
  9.    
  10. $three =function()use (&$result)  
  11. { var_dump($result); };  
  12.    
  13. $result++;  
  14.    
  15. $one();   // outputs NULL: $result is not in scope  
  16. $two();   // outputs int(0): $result was copied  
  17. $three();   // outputs int(1)  


使用引用和不使用引用就代表了是调用时赋值,还是申明时候赋值

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值