首頁  >  文章  >  後端開發  >  PHP中的閉包與匿名函數分析

PHP中的閉包與匿名函數分析

小云云
小云云原創
2017-12-25 16:42:061391瀏覽

閉包是指在建立時封裝周圍狀態的函數。即使閉包所在的環境不存在了,閉包中封裝的狀態依然存在。 PHP閉包和匿名函數使用的句法與普通函數相同,但閉包和匿名函數其實是偽裝成函數的物件(Closure類別的實例) 。以下跟大家介紹PHP中的閉包和匿名函數知識,需要的朋友參考下吧,希望能幫助大家。

匿名函數就是沒有名稱的函數。匿名函數可以賦值給變量,也能像其他任何PHP物件一樣傳遞。不過匿名函數仍是函數,因此可以調用,還可以傳入參數。匿名函數特別適合作為函數或方法的回調。

注意:理論上講,閉包和匿名函數是不同的概念。不過,PHP將其視為相同的概念。所以,我們提到閉包時,指的也是匿名函數,反之亦然。

PHP閉包和匿名函數使用的句法與普通函數相同,但閉包和匿名函數其實是 偽裝成函數的物件(Closure類別的實例) 。

建立閉包

$closure = function($name){
  return sprintf("Hello %s", $name);
}
echo $closure("jerry");
// 检测$closure变量是否是一个闭包
var_dump($closure instanceof Closure);

以上程式碼建立了一個閉包對象,然後將其賦值給 $closure 變數。閉包和普通的PHP函數很像,使用的句法相同,也接收參數,而且能回傳值。

說明:我們之所以能夠呼叫 $closure 變量,是因為這個變數的值是一個閉包,而且閉包物件實作了 __invoke() 魔術方法。只要變數名後有 () ,PHP就會找出並呼叫 __invoke() 方法。

使用閉包

我們通常把PHP閉包當作當函數和方法的回調使用。很多PHP函數都會用到回呼函數,例如array_map() 和preg_replace_callback() .如下範例,我們將用array_map() 處理數組,將數組每一項自增1:

$nubmers = array_map(function($number){
  return $number++;
}, [1,2,3]);
var_dump($numbers);

附加狀態

PHP閉包不會像真正的javascrypt閉包那樣自動封裝應用的狀態,我們必須手動呼叫閉包物件的bindTo() 方法或使用use 關鍵字,把狀態附加到PHP閉包上。

使用 use 關鍵字

使用 use 關鍵字來附加閉包狀態更加常見,因此我們先來看這種方式。使用 use 關鍵字把變數附加閉包上時,附加的變數會記住附加時賦給它的值。

function Car ($name){
  return function($statu)use($name){
    return sprintf("Car %s is %s", $name, $statu); 
  }
}
// 将车名封装在闭包中
$car = Car("bmw");
// 调用车的动作
// 输出--> "bmw is running"
echo $car("running");

注意:使用 use 關鍵字可以把多個參數傳入閉包,此時要像PHP函數或方法的參數一樣,使用逗號分隔多個參數。

使用 bindTo() 方法附加閉包的狀態

與其它PHP物件類似,每個閉包實例都可以使用 $this 關鍵字取得閉包的內部狀態。閉包物件的預設狀態沒什麼用,不過有一個 __invoke() 魔術方法和 bindTo() 方法。

bindTo() 方法為閉包增加了一些有趣的潛力。我們可以使用這個方法把 Closure 物件的內部狀態綁定到其它物件上。

bindTo() 方法的第二個參數很重要,其作用是指定綁定閉包的那個物件所屬的PHP類別。因此,閉包可以存取綁定閉包的物件中受保護和私有的成員變數。

class TestClosure
{
  private $name=[];
  private $age;
  private $sex;
  public function addPerson($name, $personCallback){
    // 将闭包对象绑定当前实例
    $this->name[$name] = $personCallback->bindTo($this, __CLASS__);
  }
  public function display($name){
    foreach ($this->name as $key => $callback){
      if($key == $name){
        // 执行闭包对象,将闭包状态附加到类
        $callback();
      }
    }
    echo "name : {$name}\n";
    echo "age : {$this->age}\n";
    echo "sex : {$this->sex}\n";
  }
}
$person = new TestClosure();
$person->addPerson("jerry", function(){
  $this->age = 19;
  $this->sex = "man";
});
$person->display("jerry");
/** output
name : jerry
age : 19
sex : man
*/

相關推薦:

PHP如何用閉包取得外部變數

深入理解javascript閉包

匿名函數、巢狀函數、閉包分別是什麼

#

以上是PHP中的閉包與匿名函數分析的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn