php的闭包(Closure)匿名函数详解
《PHP实例:php的闭包(Closure)匿名函数详解》要点: PHP应用php的闭包(Closure)也便是匿名函数,是PHP5.3引入的. 闭包的语法很简单,必要注意的关键字就只有use,use是连接闭包和外界变量.
代码如下:
$a = function() use($b) {} 简单例子如下:
代码如下:
function callback($fun) { $fun(); } $msg = "Hello,everyone"; $fun = function () use($msg) { print "This is a closure use string value,msg is: $msg. <br />/n"; }; $msg = "Hello,everybody"; callback($fun); 结果是:This is a closure use string value,msg is: Hello,everyone. <br />/n 在PHP新开放的闭包语法中,我们用use来使用闭包外部定义的变量的.这里我们使用了外部变量$msg,定义完之后,又对其值进行了改变,闭包被执行后输出的是原始值.以传值方式传递的基础类型参数,闭包use的值在闭包创建是就确定了. 小应用如下:
代码如下:
/** ?* 一个利用闭包的计数器产生器 ?* 这里其实借鉴的是python中介绍闭包时的例子... ?* 我们可以这样考虑: ?*????? 1. counter函数每次调用,创建一个局部变量$counter,初始化为1. ?*????? 2. 然后创建一个闭包,闭包产生了对局部变量$counter的引用. ?*????? 3. 函数counter返回创建的闭包,并销毁局部变量,但此时有闭包对$counter的引用,? ?*????????? 它并不会被回收,因此,我们可以这样理解,被函数counter返回的闭包,携带了一个游离态的 ?*????????? 变量. ?*????? 4. 由于每次调用counter都会创建独立的$counter和闭包,因此返回的闭包相互之间是独立的. ?*????? 5. 执行被返回的闭包,对其携带的游离态变量自增并返回,得到的便是一个计数器. ?* 结论: 此函数可以用来生成相互独立的计数器. ?*/? function counter() {? ??? $counter = 1;? ??? return function() use(&$counter) {return $counter ++;};? }? $counter1 = counter();? $counter2 = counter();? echo "counter1: " . $counter1() . "<br />/n";? echo "counter1: " . $counter1() . "<br />/n";? echo "counter1: " . $counter1() . "<br />/n";? echo "counter1: " . $counter1() . "<br />/n";? echo "counter2: " . $counter2() . "<br />/n";? echo "counter2: " . $counter2() . "<br />/n";? echo "counter2: " . $counter2() . "<br />/n";? echo "counter2: " . $counter2() . "<br />/n";? ?> 闭包的作用 1. 减少foreach的循环的代码
代码如下:
<?php // 一个基本的购物车,包括一些已经添加的商品和每种商品的数量. // 其中有一个办法用来计算购物车中所有商品的总价格.该办法使用了一个closure作为回调函数. class Cart { ??? const PRICE_BUTTER? = 1.00; ??? const PRICE_MILK??? = 3.00; ??? const PRICE_EGGS??? = 6.95; ??? protected?? $products = array(); ??? public function add($product,$quantity) ??? { ??????? $this->products[$product] = $quantity; ??? } ??? public function getQuantity($product) ??? { ??????? return isset($this->products[$product]) ? $this->products[$product] : ?????????????? FALSE; ??? } ??? public function getTotal($tax) ??? { ??????? $total = 0.00; ??????? $callback = ??????????? function ($quantity,$product) use ($tax,&$total) ??????????? { ??????????????? $pricePerItem = constant(__CLASS__ . "::PRICE_" . ??????????????????? strtoupper($product)); ??????????????? $total += ($pricePerItem * $quantity) * ($tax + 1.0); ??????????? }; ??????? //使用用户自定义函数对数组中的每个元素做回调处理 ??????? array_walk($this->products,$callback); ??????? return round($total,2);; ??? } } $my_cart = new Cart; // 往购物车里添加条目 $my_cart->add('butter',1); $my_cart->add('milk',3); $my_cart->add('eggs',6); // 打出出总价格,其中有 5% 的销售税. print $my_cart->getTotal(0.05) . "n"; // The result is 54.29 ?> 这里如果我们改造getTotal函数必然要使用到foreach. 2. 减少函数的参数
代码如下:
function html($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"; ??? }; } 如果是使用平时的办法,我们会把inner放到html函数参数中,这样不管是代码阅读还是使用都不如使用闭包. 3. 解除递归函数
代码如下:
<?php $fib = function($n) use(&$fib) { ??? if($n == 0 || $n == 1) return 1; ??? return $fib($n - 1) + $fib($n - 2); }; echo $fib(2) . "n"; // 2 $lie = $fib; $fib = function(){die('error');};//rewrite $fib variable echo $lie(5); // error?? because $fib is referenced by closure 注意上题中的use使用了&,这里不使用&会出现错误fib(n-1)是找不到function的(前面没有定义fib的类型) 所以想使用闭包解除循环函数的时候就必要使用
代码如下:
<?php $recursive = function () use (&$recursive){ // The function is now available as $recursive } 这样的形式. 4. 延迟绑定 如果你必要延迟绑定use里面的变量,你就必要使用引用,否则在定义的时候就会做一份拷贝放到use中
代码如下:
<?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) 使用引用和不使用引用就代表了是调用时赋值,还是申明时候赋值 小伙伴们是否对PHP的匿名函数也便是闭包函数有了新的认识了呢,希望本文能给大家一些提示,希望大家能够喜欢. 《PHP实例:php的闭包(Closure)匿名函数详解》是否对您有启发,欢迎查看更多与《PHP实例:php的闭包(Closure)匿名函数详解》相关教程,学精学透。编程之家 52php.cn为您提供精彩教程。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |