php闭包绑定

在PHP5.3中引入了匿名函数,当在PHP中定义一个匿名函数的时候会产生一个Closure对象,也就是闭包。在PHP5.4起这个对象加入了一些方法,用来对这个闭包对象进行更多的控制。主要是Closure的bind静态方法(Closure也有一个bindTo非静态方法,但功能基本上和bind方法一样)。

网上对PHP闭包的绑定的介绍比较少,我之前也没有怎么用过,只是自己查了一下手册,写了一些测试性质的代码,大致知道了闭包的绑定是怎么用的。

函数原型

public static Closure Closure::bind ( Closure $closure , object $newthis [, mixed $newscope = "static' ] )

第一个参数$closure就是一个闭包对象,第二个参数是这个闭包绑定的$this指针,第三个是闭包的新的作用域。

对于前面两个参数应该不需要多说就知道了,无非是绑定了之后闭包中的$this变成了指向了$newthis这个对象。第三个对象比较难理解,官方是这个注释的。

想要绑定给闭包的类作用域,或者 'static' 表示不改变。如果传入一个对象,则使用这个对象的类型名。 类作用域用来决定在闭包中 $this 对象的 私有、保护方法 的可见性。 The class scope to which associate the closure is to be associated, or 'static' to keep the current one. If an object is given, the type of the object will be used instead. This determines the visibility of protected and private methods of the bound object.

 大致反应出是与类的作用域相关。WEB应用开发网(http://www.zeroplace.cn/)写了下面的实验的代码。可能只测试出了某个侧面,如果不对,希望大家费一点点时间留言指正。

<?php
class BaseClass {
    protected function callMethod(){
        return "callBaseMethod';
    }
    
    private function test() {
        return 'test';
    }
}

class MyClass extends BaseClass {
    protected function callMethod() {
        return 'callMyMethod';
    }
    
    public function testBind() {
        $cl = function(){
            echo $this->callMethod();
            echo $this->test();
        };
        
        $bind = Closure::bind($cl, $this, MyClass::class);
        $bind();
    }
}

$my = new MyClass();
$my->testBind();

此时会报出一个错误,如下。

callMyMethod
Fatal error: Call to private method BaseClass::test() from context "MyClass' in C:\wamp\www\laravel\Test.php on line 20

如果把Closure这句改成

$bind = Closure::bind($cl, $this, BaseClass::class);

输出就没有报错了

callMyMethodtest

也就是说,$newscope这个参数指定的新的作用域决定了$this指针可以访问哪个类下面的private和protected方法。

 



文章来自: 本站原创
Tags:
评论: 0 | 查看次数: 8726