publicstatic Closure Closure::bind ( Closure $closure , object$newthis [, mixed$newscope = 'static' ] )
1、函數意義:php
對於 Closure::bind PHP官方文檔的解釋是:「Closure::bind — 複製一個閉包,綁定指定的$this對象和類做用域。」閉包
閉包:即匿名函數,匿名函數的另外一種叫法。因此前半句的意思,就是「複製一個匿名函數」。ide
後半句話,就比較拗口了,「綁定指定的$this對象和類的做用域」。個人理解是:「$this對象」直接理解爲「被new()建立的對象」;「類的做用域」即定義類的大括號中間的所有內容。函數
至於「綁定」,意思就是,匿名函數在執行時,函數內部的$this(若是函數內部有[$this->成員名]的這種用法的話)是被綁定的,綁定的對象就是參數二的 $newthis;固然,$this確定是用來被綁定類的實例的,若是想訪問類的靜態成員的話,就因該用 【類名::成員名】或者【static::成員名】或者【self::成員名】。this
全部,Closure::bind()是匿名函數在處理時,用來綁定類的對象和做用域的(我以爲說成「或」應該更準確一些,如今不用細究,後面會講到),因此若是你只是單純的用匿名函數可是卻不須要綁定類對象或者制定這個匿名函數的類的做用域的話,就不須要用Closure::bind()方法了。spa
2、參數說明和用法:.net
2.1 第一個參數$closure,其實就是一個匿名函數,之因此參數類型是Closure,這是由於「匿名函數目前是經過 Closure 類來實現的」。code
2.2 第二個參數$newthis,若是匿名函數須要用到類實例的話,就必須傳一個類的實例;若是不須要的話,這個參數直接傳「null」就能夠。對象
2.3 第三個參數$newscope,scope的中文意思爲「範圍,做用域」。若是不指定這個參數,那麼默認,在匿名函數內部,只能使用經過$newthis這個參數傳入進來的對象的pulic成員;而若是指定了這個參數的話,那麼就可訪問這個參數所表示的類的做用域內部的全部成員,包括private和protected。blog
3、舉個栗子:
class T { private static $name = '我是T裏面的私有屬性 $name <br>'; private function show() { echo "我是T裏面的私有函數:show <br>"; } protected function who() { echo "我是T裏面的保護函數:who <br>"; } public function name() { echo "我是T裏面的公共函數:name <br>"; } } $test = new T(); $func = Closure::bind(function () { $this->who(); $this->name(); $this->show(); }, $test ); $func();
結果:
Fatal error: Uncaught Error: Call to protected method T::who()
who是protected的,怎麼能夠在類的外部(類的做用域外)訪問呢?,可是咱們稍加改造一下:
1 class T { 2 3 private static $name = '我是T裏面的私有屬性 $name <br>'; 4 5 private function show() { 6 echo "我是T裏面的私有函數:show <br>"; 7 } 8 9 protected function who() { 10 echo "我是T裏面的保護函數:who <br>"; 11 } 12 13 public function name() { 14 echo "我是T裏面的公共函數:name <br>"; 15 } 16 } 17 18 $test = new T(); 19 20 $func = Closure::bind(function () { 21 $this->who(); 22 $this->name(); 23 $this->show(); 24 }, $test, 25 T::class//加這個,指定匿名函數能夠使用T這個類的做用域。下面兩種方式均可以 26 //'T' 27 //new T() 28 ); 29 30 $func();
結果:
是否是很神奇,類的protected和private的成員也能夠在類的外部訪問。能夠理解爲,第三個參數,等因而受權了匿名函數,你能夠到某個類的做用域內部來訪問類的全部成員(包括靜態和非靜態)。
那麼怎麼在匿名函數內,訪問靜態成員呢?很簡單,就和真的在類的內部同樣,能夠使用[self::]或者[類名::]或者[static::]。
具體:
1 class T { 2 3 private static $name = '我是T裏面的私有屬性 $name <br>'; 4 5 private function show() { 6 echo "我是T裏面的私有函數:show <br>"; 7 } 8 9 protected function who() { 10 echo "我是T裏面的保護函數:who <br>"; 11 } 12 13 public function name() { 14 echo "我是T裏面的公共函數:name <br>"; 15 } 16 } 17 18 $test = new T(); 19 20 $func = Closure::bind(function () { 21 $this->who(); 22 $this->name(); 23 $this->show(); 24 25 echo self::$name; //訪問靜態私有成員 26 echo static::$name; //訪問靜態私有成員 27 }, $test, 28 T::class//加這個,指定匿名函數能夠使用T這個類的做用域。下面兩種方式均可以 29 //'T' 30 //new T() 31 ); 32 33 $func();
結果: