如何理解 PHP 匿名函数,闭包?二者有什么关系?

php 匿名函数主要有两个应用场景:

变量赋值;函数/方法参数;

先看二段匿名函数代码(自己写下这二个闭包分别输出什么值):

$example = function () {
    var_dump($message);
};
echo $example();
$message = 'hello';
$example = function () use ($message) {
    var_dump($message);
};
echo $example();

上面二个匿名函数被调用时,分别输出 NULL,string(5) "hello"。

下面分析下匿名函数是如何被执行的:

匿名函数在赋值给一个变量时,PHP 会自动进行转化,即把匿名函数转化为闭包的实例,闭包实例内有个方法 __invoke(),__invoke() 的方法体为匿名函数的方法体。所以匿名函数赋值给变量,变量的类型其实是 object,也是闭包类 Closure 的实例。

由原理可知,执行 $example() 时,其实是把 $example 当函数一样调用,会自动触发方法 __invoke()。

__invoke() 说明:

它是 PHP 的一个魔术方法,尝试以调用函数的方式调用一个对象时,__invoke() 会被自动调用。

上面二段代码,第二段为啥会输出 hello 呢?在输出 hello 前,代码到底发生了什么变化?

1,通过匿名函数给变量赋值时,匿名函数自动进行了闭包的实例化。

2,实例化时,use 后面的变量会作为实例的属性,变量值会作为属性值。可以理解为:

$message = 'hello';
$example = function () use ($message) {
    var_dump($message);
};

等价于:

$example = new Closure();
$example->message = 'hello';
// 以及下一步讲的 __invoke()

3,匿名函数的函数体会成为 __invoke() 的函数体。匿名函数体用到的变量有二种,一种是匿名函数参数,另一种是 use 后面的变量,参数和平时类的方法参数传递及使用没有区别,但是 use 后面的变量 $message 会在函数体内变为 $this->message。

$example 的打印结果:

附加一段代码,进一步理解一下匿名函数:

function enclosePerson($name)
{
    return function ($doCommand) use ($name) {
        return sprintf('%s , %s', $name, $doCommand);
   };
}
//把字符串“Clay”封装在闭包中
$clay = enclosePerson('Clay');
//传入参数,调用闭包
echo $clay('get me sweat tea!'); // Clay, get me sweat tea!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值