bind是bindTo的靜態版本,因此只說bind吧。(還不是太了解為什么要弄出兩個版本)
官方文檔: 復制一個閉包,綁定指定的$this對象和類作用域。
其實后半句表述很不清楚。 我的理解: 把一個閉包轉換為某個類的方法(只是這個方法不需要通過對象調用), 這樣閉包中的$this、static、self就轉換成了對應的對象或類。
因為有幾種情況:
1、只綁定$this對象.
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();
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();
My name is php, I’m 100 years old.
注意: 在上面的例子中,是不可以在$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中同時使用$this和static
4、都不綁定.(這樣一來只是純粹的復制, 文檔說法是使用cloning代替bind或bindTo)
$closure = function () {
echo "bind nothing.\n";
};
//與$bound_closure = clone $closure;的效果一樣
$bound_closure = Closure::bind($closure, null);
$bound_closure();
bind nothing.
這個就用clone好了吧…
