<dd id="y7hvi"><strong id="y7hvi"></strong></dd>
<output id="y7hvi"><pre id="y7hvi"></pre></output>
    <label id="y7hvi"></label>
    <small id="y7hvi"><menu id="y7hvi"><del id="y7hvi"></del></menu></small><listing id="y7hvi"><menu id="y7hvi"><s id="y7hvi"></s></menu></listing>
    <label id="y7hvi"><button id="y7hvi"></button></label><small id="y7hvi"></small>

    <listing id="y7hvi"></listing>
      您的位置 >>> 星想互聯 >>> 編程技術 >>> PHP基礎
      深刻理解閉包,php中的closure使用詳解
      點擊數:438  發布時間2020-06-06 22:49:39
      Closure英文在計算機術語中是閉包的意思。PHP手冊中又解釋Closure是用于代表匿名函數的類.。
      匿名函數,顧名思義是沒有名字的函數。其中,匿名函數也叫閉包函數。
      閉包,在百度百科中的意思是能夠讀取其他函數內部變量的函數。
      而在php中,別人會告訴你,閉包的功能是內部函數中可以使用外部變量。那么誰是對的呢?
      那我們來了解一下。

      $closure = function(){echo "hello";}; // 首先我們創建一個匿名函數
      var_dump($closure); // 輸出object(Closure)#1 (0) { }

      $closure(); // 輸出hello


      由此我們可以看出創建一個匿名函數,實際上是創建了一個Closure類的對象。
      所以closure其實是一個偽裝成函數的對象。

      匿名函數很好理解,那么什么是閉包呢?

      首先,比如我們在下面模擬一個計數器功能,在php中我們想用一個函數去訪問外部的變量。
      代碼如下:

      //直接訪問
      $count = 0;
      function add(){
      echo $count++;
      }
      add(); // error  無法調用$count,提示Undefined variable: count

      //接下來我們試著用匿名函數來實現
      $count = 0;
      $add = function(){
      echo $count++;
      };
      $add(); // error  依然無法調用$count,提示Undefined variable: count

      //通過關鍵字use來鏈接函數與外部變量
      $count = 0;
      $add = function() use($count){
      echo $count++;
      };
      $add(); // 0  可以訪問$count了
      $add(); // 0  但$count依然是0,但我們想讓數目增加。哦,原來$count只是一份副本,要$count保存原值進行操作要加上&

      //然后,我們在use括號里加上&
      $count = 0;
      $add = function() use(&$count){
      echo $count++;
      };
      $add(); // 0
      $add(); // 1  終于成功了!
      $add(); // 2 繼續累加


      但是呢?上面的count是一個全局變量,任何外部方法都可以去改變它,為確保獨立性。比如是一篇文章的瀏覽次數。
      我們將count放入一個函數中。以下:

      function add(){
      $count = 0;
      return function() use(&$count){echo $count++;};
      }
      $a=add();
      $a(); // 0
      $a(); // 1

      這也是成功的。我們理解了,閉包的實現的功能的確是內部函數中可以使用外部變量。

      那么,接下來我們,比較一下javascript代碼與php代碼的區別

      //javascript代碼
      function a(){
      var i=0;
      function b(){
      alert(++i);
      }
      return b;
      }
      var c=a();
      c(); // 1
      c(); // 2

      對比上述兩種語言的代碼,實現了相同的功能。

      在JavaScript中,函數a的嵌套函數b由于作用域鏈的關系,能夠讀取它的外部變量i,嵌套函數是由名字的。
      而在php中,這必須通過use關鍵字來鏈接外部變量,并且函數本身是沒名字的。
      當然對于外部來說,js代碼的函數c的確是能夠讀取其他函數(a)的內部變量(i)的函數,當然它的本質是函數b。
      在上述php代碼中,函數a也的確是能夠讀取其他函數(add)的內部變量($count)的函數,它的本質當然也是閉包函數。

      所以,雖然說法不同,但兩者都實現了閉包,說的是同樣的意思。

      接下來,我們創建一個參數完整的閉包函數,看看closure里面到底有什么。

      //首先創建了一個Apple類
      Class Apple{
      public static $name = "apple";
      public $color ="red";
      private $money = 10;
      public function getClosure(){
      $ex1 = self::$name;
      $ex2 = $this->money;
      return function($name) use($ex1,$ex2){
      echo $name."買了".$ex1."花了".$ex2;
      };
      }
      }
      $apple = new Apple();
      $c =$apple->getClosure();
      var_dump($c); //輸出閉包。

      //輸出格式如下
      object(Closure)#2 (3) {
      ["static"]=>
      array(2) {
      ["ex1"]=>
      string(5) "apple"
      ["ex2"]=>
      int(10)
      }
      ["this"]=>
      object(Apple)#1 (2) {
      ["color"]=>
      string(3) "red"
      ["money":"Apple":private]=>
      int(10)
      }
      ["parameter"]=>
      array(1) {
      ["$name"]=>
      string(10) "
      "
      }
      }

      從個上述的格式上來看,一個參數齊全的閉包自動添加了三個屬性,分別是:static,this和parameter。
      閉包引用的外部變量參數自動給了static屬性。
      同時,閉包所屬的對象也就是apple對象自動給了一個this屬性。
      閉包所需要輸入的參數自動給了parameter屬性,并且提示需要等待輸入。

      我們看到在php中閉包的實現,用的都是沒有名字的函數,所以匿名函數也叫閉包函數。
      ————————————————
      版權聲明:本文為CSDN博主「曉風殘月淡」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
      原文鏈接:https://blog.csdn.net/qq_40610003/java/article/details/99312506
      來源:咸寧網站建設
      新天线宝宝