闭包
目的:实现函数的复用。
php会自动把闭包函数转换为内置的Closure的对象实例,依赖Closure对象实例给闭包函数增加了更多的能力。
闭包不能被实例(私有构造函数),也不能被继承(finally类)。可以通过反射来判断闭包实例是否能被实例,继承。
匿名函数
php5.3时引入,匿名函数,又称 Anonymous functions。
- 声明一个匿名函数
$func = function($i){ return 'i:'.$i; }; echo $func(10);
实现闭包
实现方式:将匿名函数在普通函数中当作参数传递,或者 在函数中被返回。这就实现了简单的闭包。
连接闭包和外界变量的关键字: use
use引用外部变量,相当于clone副本,匿名函数内的操作不会改变该变量的上下文的值。
function numberAdd(){ $i = 1; $func = function()use($i){ $i++; echo 'i: '.$i.PHP_EOL; }; return $func; } $num = numberAdd(); $num();//i: 2 $num();//i: 2 $num();//i: 2
可使用 & 来指向变量地址,来达到改变上下文值的目的。
将匿名函数返回给外界后,$i引用变量便被保存了,提升为全局变量。后面多次调用,传入的均为上一次保存后的值。
function numberAdd(){ $i = 1; $func = function()use(&$i){ $i++; echo 'i: '.$i.PHP_EOL; }; return $func; } $num = numberAdd(); $num();//i: 2 $num();//i: 3 ,这里多次调用的是匿名函数$func ,并非numberAdd(),故$i并未每次被重新初始值。 $num();//i: 4
绑定的概念
访问类下的匿名函数,即该匿名函数的访问范围不再是全局的,而是该类的访问范围。那么,就需要先 “将匿名函数绑定到类中” 。
PHP Closure类用于代表匿名函数的类,Closure类摘要如下:
Closure { __construct ( void ) //用于禁止实例化的构造函数 public static Closure bind (Closure $closure , object $newthis [, mixed $newscope = 'static' ]) //复制一个闭包,绑定指定的$this对象和类作用域 public Closure bindTo (object $newthis [, mixed $newscope = 'static' ]) //复制当前闭包对象,绑定指定的
$this
对象和类作用域。
}
参数说明:
$closure 需要绑定的匿名函数。
$newthis 需要绑定的匿名函数的对象,或者null创建未绑定的闭包。如果闭包中使用“$this”(使用$this只能调用非静态属性),则该参数不可以为null,只能是object对象。
$newscope 想要绑定给闭包的作用域。如果传入一个对象,则使用这个对象的类型名。类作用域用来决定在闭包中$this对象的private(私有)、protected(受保护的)的可见性。
默认参数”static“表示这个闭包和外部变量的作用域一样,不能访问类的私有和保护方法。
如果闭包中访问的是private或protected属性,则需要该参数来提升权限。
demo 函数复用实例
把函数挂在不同的类或对象上
class User{ private $age = 30; private static $weight = 70; protected $height = 170; protected static $numLove = 6; public $name = 'KD'; public static $six = 'man'; } $funcName = function(){ return $this->name; }; $name = Closure::bind($funcName, new User()); echo $name().PHP_EOL; //echo KD $funcHeight = function(){ return $this->height; }; $height = Closure::bind($funcHeight, new User(), new User()); echo $height().PHP_EOL; //echo 170 $funcNumLove = static function(){ return self::$numLove; //ok // return User::$numLove; //ok ,IDE可能会出现错误提醒,但可以正常运行 }; $numberLove = Closure::bind($funcNumLove, null, new User()); echo $numberLove().PHP_EOL; //echo 6 $numberLove = Closure::bind($funcNumLove, null, 'User'); echo $numberLove().PHP_EOL; //echo 6
闭包函数的实际应用
class Cart{ //定义价格 const PRICE_MILK = 2.5; const PRICE_COCO = 3; const PRICE_MEAT = 36; public $goods = array(); function addCart($good, $number){ $this->goods[$good] = $number; } /** * 根据税率计算总价 * @param $rate 税率 * @return float */ function getTotal($rate){ $total = 0; //匿名函数,获取商品数量后,根据税率计算价格 $func = function($number, $good) use ($rate, &$total){ $price = constant(__CLASS__."::".strtoupper('price_'.$good)); //返回常量的值 $total += $price * $number * (1+$rate); }; //循环处理购物车中的商品,累计 array_walk($this->goods, $func); return round($total); } } $cart = new Cart(); $cart->addCart('milk', 10); $cart->addCart('coco', 1); $cart->addCart('meat', 1); $total = $cart->getTotal(0.2); print_r($total); //echo 77
参考地址:PHP Closure(闭包)类详解
标签:闭包,Closure,函数,function,echo,匿名 From: https://www.cnblogs.com/wanghaokun/p/17816494.html