PHP Closure 匿名类

闭包函数特点

闭包函数不能直接访问闭包外的变量,而是通过use 关键字来调用上下文变量(闭包外的变量),也就是说通过use来引用上下文的变量;

闭包内所引用的变量不能被外部所访问(即,内部对变量的修改,外部不受影响),若想要在闭包内对变量的改变从而影响到上下文变量的值,需要使用&的引用传参

Closure

PHP Closure 类是用于代表匿名函数的类,匿名函数(在 PHP 5.3 中被引入)会产生这个类型的对象,Closure类摘要如下:

Closure {
    __construct ( void )
    public static Closure bind (Closure $closure , object $newthis [, mixed $newscope = 'static' ])
    public Closure bindTo (object $newthis [, mixed $newscope = 'static' ])
}

方法说明:
Closure::__construct — 用于禁止实例化的构造函数
Closure::bind — 复制一个闭包,绑定指定的$this对象和类作用域。
Closure::bindTo — 复制当前闭包对象,绑定指定的$this对象和类作用域。

除了此处列出的方法,还有一个 __invoke 方法。这是为了与其他实现了 __invoke()魔术方法 的对象保持一致性,但调用闭包对象的过程与它无关。

参数说明:
closure表示需要绑定的闭包对象。
newthis表示需要绑定到闭包对象的对象,或者NULL创建未绑定的闭包。
newscope表示想要绑定给闭包的类作用域,可以传入类名或类的示例,默认值是 'static', 表示不改变。

返回值:成功时返回一个新的 Closure 对象,失败时返回FALSE

bind

class Animal {
    public $cat = 'cat';
    public static $dog = 'dog';
    private $pig = 'pig';
    private static $duck = 'duck';
}
 
//不能通过 $this 访问静态变量
//不能通过 类名::私有静态变量,只能通过self,或者static,在类里面访问私有静态变量
 
$cat = function() {
    return $this->cat;
};
 
$dog = static function () {
    return Animal::$dog;
};
 
$pig =  function() {
    return $this->pig;
};
 
$duck = static function() {
    //return Animal::$duck;  这样写,会报错,提示不能通过类名访问私有静态变量
  return self::$duck; // return static::$duck
};
 
$bindCat = Closure::bind($cat, new Animal(), 'Animal');
$bindCat2 = Closure::bind($cat, new Animal(), new Animal());
echo $bindCat() . PHP_EOL;
echo $bindCat2() . PHP_EOL;
 
$bindDog = Closure::bind($dog, null, 'Animal');
$bindDog2 = Closure::bind($dog, null, new Animal());
echo $bindDog() . PHP_EOL;
echo $bindDog2() . PHP_EOL;
 
$bindPig = Closure::bind($pig, new Animal(), 'Animal');
$bindPig2 = Closure::bind($pig, new Animal(), new Animal());
echo $bindPig() . PHP_EOL;
echo $bindPig2() . PHP_EOL;
 
$bindDuck = Closure::bind($duck, null, 'Animal');
$bindDuck2 = Closure::bind($duck, null, new Animal());
echo $bindDuck() . PHP_EOL;
echo $bindDuck2() . PHP_EOL;

结论

  1. 闭包内如果用 $this, 则 $this 只能调用非静态的属性,这和实际类中调用原则是一致的,且 Closure::bind() 方法的第2个参数不能为null,必须是一个实例 (因为$this,必须在实例中使用),第三个参数可以是实例,可以是类字符串,或 static;

  2. 闭包内调用静态属性时,闭包必须声明为 static,同时Closure::bind()方法的第2个参数需要为null,因为 静态属性不需要实例,第3个参数可以是类字符串,实例,staic

  3. bindTo与bind类似,是面向对象的调用方式

你可能感兴趣的:(PHP Closure 匿名类)