PHP 閉包 bind和bindto

bind是bindTo的靜態版本,因此只說bind吧。(還不是太瞭解爲什麼要弄出兩個版本)

官方文檔: 複製一個閉包,綁定指定的$this對象和類作用域。

其實後半句表述很不清楚。 我的理解: 把一個閉包轉換爲某個類的方法(只是這個方法不需要通過對象調用), 這樣閉包中的$this、static、self就轉換成了對應的對象或類。

因爲有幾種情況:

1、只綁定this.2.3this對象. 2、只綁定類作用域. 3、同時綁定this對象和類作用域.(文檔的說法)
4、都不綁定.(這樣一來只是純粹的複製, 文檔說法是使用cloning代替bind或bindTo)

下面詳細講解這幾種情況:

1、只綁定$this對象

$closure = function ($name, $age) {
    $this->name = $name;
    $this->age = $age;
};
 
class Person {
    public $name;
    public $age;
 
    public function say() {
        echo "My name is {$this->name}, I'm {$this->age} years old.\n";
    }
}
 
$person = new Person();
 
//把$closure中的$this綁定爲$person
//這樣在$bound_closure中設置name和age的時候實際上是設置$person的name和age
//也就是綁定了指定的$this對象($person)
$bound_closure = Closure::bind($closure, $person);
 
$bound_closure('php', 100);
$person->say();

1
My name is php, I’m 100 years old.
注意: 在上面的這個例子中,是不可以在$closure中使用static的,如果需要使用static,通過第三個參數傳入帶命名空間的類名。

2、只綁定類作用域.

$closure = function ($name, $age) {
  static::$name =  $name;
  static::$age = $age;
};
 
class Person {
    static $name;
    static $age;
 
    public static function say()
    {
        echo "My name is " . static::$name . ", I'm " . static::$age. " years old.\n";
    }
}
 
//把$closure中的static綁定爲Person類
//這樣在$bound_closure中設置name和age的時候實際上是設置Person的name和age
//也就是綁定了指定的static(Person)
$bound_closure = Closure::bind($closure, null, Person::class);
 
$bound_closure('php', 100);
 
Person::say();
  

1
My name is php, I’m 100 years old.
注意: 在上面的例子中,是不可以在closure使closure中使用this的,因爲我們的bind只綁定了類名,也就是static,如果需要使用$this,新建一個對象作爲bind的第二個參數傳入。

3、同時綁定$this對象和類作用域.(文檔的說法)

$closure = function ($name, $age, $sex) {
    $this->name = $name;
    $this->age = $age;
    static::$sex = $sex;
};
 
class Person {
    public $name;
    public $age;
 
    static $sex;
 
    public function say()
    {
        echo "My name is {$this->name}, I'm {$this->age} years old.\n";
        echo "Sex: " . static::$sex . ".\n";
    }
}
 
$person = new Person();
 
//把$closure中的static綁定爲Person類, $this綁定爲$person對象
$bound_closure = Closure::bind($closure, $person, Person::class);
$bound_closure('php', 100, 'female');
 
$person->say();
  

My name is php, I’m 100 years old. Sex: female.
在這個例子中可以在closure使closure中同時使用this和static

4、都不綁定.(這樣一來只是純粹的複製, 文檔說法是使用cloning代替bind或bindTo)

$closure = function () {
    echo "bind nothing.\n";
};
 
//與$bound_closure = clone $closure;的效果一樣
$bound_closure = Closure::bind($closure, null);
 
$bound_closure();

1
bind nothing.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章