共计 1765 个字符,预计需要花费 5 分钟才能阅读完成。
在之前的文章中,咱们曾经学习过匿名函数的应用,没有看过的小伙伴能够进入传送门先去理解下闭包匿名函数的用法,传送:还不晓得 PHP 有闭包?那你真 OUT 了。
对于闭包匿名函数,在 JS 中有个很典型的问题就是要给它绑定一个 this 作用域。其实这个问题在 PHP 中也是存在的,比方上面这段代码:
$func = function($say){echo $this->name, ':', $say, PHP_EOL;};
$func('good'); // Fatal error: Uncaught Error: Using $this when not in object context
在这个匿名函数中,咱们应用了 \$this->name 来获取以后作用域下的 $name 属性,可是,这个 $this 是谁呢?咱们并没有定义它,所以这里会间接报错。错误信息是:应用了 $this 然而没有对象上下文,也就是说没有指定 $this 援用的作用域。
bindTo() 办法绑定 $this
好吧,那么咱们就给它一个作用域,和 JS 一样,应用一个 bindTo() 办法即可。
$func1 = $func->bindTo($lily, 'Lily');
// $func1 = $func->bindTo($lily, Lily::class);
// $func1 = $func->bindTo($lily, $lily);
$func1('cool');
这回就能够失常输入了。bindTo() 办法是复制一个以后的闭包对象,而后给它绑定 $this 作用域和类作用域。其中,$lily 参数是一个 object $newthis 参数,也就是给这个复制进去的匿名函数指定 $this。而第二个参数 ‘Lily’ 则是绑定一个新的 类作用域,它代表一个类型、决定在这个匿名函数中可能调用哪些 公有 和 受爱护 的办法,上例中给出的三种形式都能够用来定义这个参数。如果不给这个参数,那么咱们就不能拜访这个 private 的 $name 属性了:
$func2 = $func->bindTo($lily);
$func2('cool2'); // Fatal error: Uncaught Error: Cannot access private property Lily::$name
call() 办法绑定 $this
在 PHP7 当前,PHP 新减少了 call() 办法来进行匿名函数的 $this 绑定,咱们来看看它和 bindTo() 办法有哪些区别。
$func->call($lily, 'well'); // Lily:well
额 ……
是不是感觉不便好多。首先,它间接执行了,不须要再赋值给一个变量,也就是说,它不是去复制那个闭包函数的而是间接执行了;其次,没有 类作用域 这个概念了,第一个参数还是指定新的 $this 的指向,而前面的参数就是原来闭包函数的参数。
尽管很不便,然而它也带来了另一个问题,因为没有 类作用域 的限度,所以会毁坏封装。你好不容易做好的面向对象的设计,封装了一堆属性,而后应用这个 call() 就让对象的所有 公有 和 受爱护 内容都裸露了进去。当然,这也是看咱们本人的业务状况了,毕竟两种模式咱们在写代码的时候都是能够自由选择的。
总结
其实包含闭包函数在内,这些个性都十分像 JS。这也是语言交融的一种趋势,不论是学习了 JS 来看 PHP 的这些个性还是先学了 PHP 再去看 JS,都会让咱们更容易了解它们的作用与能力,这就是语言个性交融带来的益处。不论怎么样,学就是了,持续加油吧!!
测试代码:
https://github.com/zhangyue0503/dev-blog/blob/master/php/202002/source/%E5%9C%A8PHP%E4%B8%AD%E5%A6%82%E4%BD%95%E4%B8%BA%E5%8C%BF%E5%90%8D%E5%87%BD%E6%95%B0%E6%8C%87%E5%AE%9Athis%EF%BC%9F.php
参考文档:
https://www.php.net/manual/zh/functions.anonymous.php
https://www.php.net/manual/zh/closure.bindto.php
https://www.php.net/manual/en/closure.call.php
各自媒体平台均可搜寻【硬核项目经理】