Closure::bind — 複製一個閉包,綁定指定的$this對象和類做用域。php
其實後半句表述很不清楚。 個人理解: 把一個閉包轉換爲某個類的方法(只是這個方法不須要經過對象調用), 這樣閉包中的$this、static、self就轉換成了對應的對象或類。閉包
建立並返回一個 匿名函數, 它與當前對象的函數體相同、綁定了一樣變量,但能夠綁定不一樣的對象,也能夠綁定新的類做用域。函數
從我我的理解,和js裏面的call函數有點相似。能夠改變閉包對象指定的做用域。this
簡單說,就是把閉包當成對象的成員方法或者靜態成員方法.code
這個方法是 Closure::bindTo() 的靜態版本對象
public static Closure::bind ( Closure $closure , object $newthis [, mixed $newscope = 'static' ] ) : Closure
closure作用域
須要綁定的匿名函數。文檔
newthisget
須要綁定到匿名函數的對象,或者 NULL 建立未綁定的閉包。io
newscope
想要綁定給閉包的類做用域,或者 'static' 表示不改變。若是傳入一個對象,則使用這個對象的類型名。 類做用域用來決定在閉包中 $this 對象的 私有、保護方法 的可見性
返回一個新的 Closure 對象 或者在失敗時返回 FALSE
範例
class A { private static $sfoo = 1; private $ifoo = 2; } $cl1 = static function() { return A::$sfoo; }; $cl2 = function() { return $this->ifoo; }; $bcl1 = Closure::bind($cl1, null, 'A'); //就至關於在類裏面加了個靜態成員方法 $bcl2 = Closure::bind($cl2, new A(), 'A'); //至關於在類裏面加了個成員方法 echo $bcl1(), "\n"; echo $bcl2(), "\n";
成員方法中使用$this訪問對象, 靜態成員方法直接使用類名::成員的方法。
可是由於返回的是匿名函數, 沒有函數名, 因此返回一個已經綁定$this對象和類做用域的閉包給你使用.
返回的閉包函數,已經綁定了$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,經過第三個參數傳入帶命名空間的類名。
把closure閉包函數中的 $this 綁定到一個對象,這樣執行閉包函數,就至關於執行對象的方法。
至關於就是在對象中添加了成員方法,因此閉包函數內的處理也就在處理對象內數據
$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的第二個參數傳入。
在這個例子中能夠在$closure中同時使用$this和static
$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 = function () { echo "bind nothing.\n"; }; //與$bound_closure = clone $closure;的效果同樣 $bound_closure = Closure::bind($closure, null); $bound_closure();//輸出:bind nothing.
這個就用clone好了吧…
Closure::bindTo — 複製當前閉包對象,綁定指定的$this對象和類做用域。
建立並返回一個 匿名函數, 它與當前對象的函數體相同、綁定了一樣變量,但能夠綁定不一樣的對象,也能夠綁定新的類做用域。
「綁定的對象」決定了函數體中的 $this 的取值,「類做用域」表明一個類型、決定在這個匿名函數中可以調用哪些 私有 和 保護 的方法。 也就是說,此時 $this 能夠調用的方法,與 newscope 類的成員函數是相同的。
靜態閉包不能有綁定的對象( newthis 參數的值應該設爲 NULL)不過仍然能夠用 bubdTo 方法來改變它們的類做用域。
public Closure::bindTo ( object $newthis [, mixed $newscope = 'static' ] ) : Closure``
newthis
綁定給匿名函數的一個對象,或者 NULL 來取消綁定。
newscope
關聯到匿名函數的類做用域,或者 'static' 保持當前狀態。若是是一個對象,則使用這個對象的類型爲心得類做用域。 這會決定綁定的對象的 保護、私有成員 方法的可見性。
返回新建立的 Closure 對象 或者在失敗時返回 FALSE
若是你只是想要複製一個匿名函數,能夠用 cloning 代替。
class A { function __construct($val) { $this->val = $val; } function getClosure() { //returns closure bound to this object and scope return function() { return $this->val; }; } } $ob1 = new A(1); $ob2 = new A(2); $cl = $ob1->getClosure(); echo $cl(), "\n"; $cl = $cl->bindTo($ob2); echo $cl(), "\n";
和 Closure::bind() 做用同樣,只是一個是靜態的調用,一個是對象的的調用。
二者功能功能同樣,不一樣的是匿名函數的來源不同,Closure::bind 是靜態調用,直接是閉包函數當參數傳入;而Closure::bindTo是對象方式調用,閉包函數是從另一個對象中獲取的,而後在綁定到其餘對象上。