闭包|匿名函数-作用域,你知道use?那你知道bindTo吗?
学习链接
闭包是啥?匿名函数什么鬼?
闭包和匿名函数在PHP 5.3.0中引入,这两个特性非常有用,每个PHP开发者都应该掌握。
闭包是指在创建时封装周围状态的函数,即使闭包所在的环境不存在了,闭包中封装的状态依然存在。
匿名函数其实就是没有名称的函数,匿名函数可以赋值给变量,还能像其他任何PHP函数对象那样传递。 不过匿名函数仍然是函数,因此可以调用,还可以传入参数,适合作为函数或方法的回调。
注:理论上讲闭包和匿名函数是不同的概念,不过PHP将其视作相同的概念(匿名函数在PHP中也叫作闭包函数),所以下面提到闭包时指的也是匿名函数;反之亦然。
喜欢较真的可以去读一下, modern-php。
2、创建闭包
创建闭包很简单:
我们 把一个函数 赋值给 变量 greet
这就创建了一个闭包。
$closure = function ($name) {
return sprintf('hello %s', $name);
};
echo $closure('Josh');
闭包和普通的PHP函数区别?
- 句法相同
- 可接受参数
- 有返回值。
- 闭包没有函数名。
我们为什么可以调用 变量greet?
因为 __invoke()
我们之所以可以调用 $closure 变量,是因为这个变量的值是一个闭包,而且闭包对象实现了__invoke()
魔术方法,只要后面跟着 ()
,PHP 就会查找__invoke()
方法。这里简单解释下这个魔术方法:
class testClass
{
public function __invoke
{
print "hello world";
}
}
$n = new testClass;
$n();
何时使用?
我们通常把 PHP 闭包当做函数和方法的回调使用。很多 PHP 函数都会用到回调函数,例如 array_map()
和 preg_replace_callback()
。
$numbersPlusOne = array_map(function($number) {
return $number + 1;
}, [1, 2, 3]);
在闭包出现之前,要实现这样的功能,PHP开发者只能单独创建具名函数,然后使用名称引用这个函数。
注意事项: 闭包作用域,常见的use,那你知道bindTo 做什么的吗?
从父作用域继承变量
1. use
2. bindTo
闭包是一个对象,所以我们可以在闭包中使用$this关键字获取闭包的内部状态,闭包对象的默认状态没什么用,需要注意的是其中的__invoke
魔术方法和bindTo
方法。
作用
把闭包的内部状态绑定到其他对象上。
参数:
这里bindTo
方法的第二个参数,其作用是指定绑定闭包的那个对象所属的PHP类,这样,闭包就可以在其他地方访问绑定闭包的对象中受保护和私有的成员变量。
你会发现,PHP框架经常使用bindTo
方法把路由URL映射到匿名回调函数上,框架会把匿名回调函数绑定到应用对象上,这样在匿名函数中就可以使用$this
关键字引用重要的应用对象。
框架中的 闭包实现:
请查看学院君的文章: 现代 PHP 新特性系列(五) —— 包和匿名函数