php 中的closure用法實例詳解

怪我咯
發布: 2017-07-11 15:46:32
原創
1439 人瀏覽過

Closure,匿名函數,又稱為Anonymous functions,是php5.3的時候引入的。匿名函數就是沒有定義名字的函數,也就是閉包(Closure。這點牢牢記住就能理解匿名函數的定義了。例如以下程式碼(檔名是do.php)

<?php
function A() {
  return 100;
};
function B(Closure $callback)
{
  return $callback();
}
$a = B(A());
print_r($a);//输出:Fatal error: Uncaught TypeError: Argument 1 passed to B() must be an instance of Closure, integer given, called in D:\web\test\do.php on line 11 and defined in D:\web\test\do.php:6 Stack trace: #0 D:\web\test\do.php(11): B(100) #1 {main} thrown in D:\web\test\do.php on line 6
?>
登入後複製

這裡的A()永遠沒有辦法用來當B的參數,因為A它並不是「匿名」函數。閉包

將匿名函數在普通函數中當做參數傳入,也可以被回傳。三個例子:

<?php
$f = function () {
  return 100;
};
function B(Closure $callback)
{
  return $callback();
}
$a = B($f);
print_r($a);//输出100
<?
$func = function( $param ) {
  echo $param;
};
$func( &#39;hello word&#39; );
//输出:hello word
登入後複製
連接閉包和外界變數的關鍵字:USE閉包可以保存所在程式碼區塊上下文的一些變數和值。不能呼叫所在程式碼區塊的上下文變量,而需要透過使用use關鍵字。到,dollar沒有在use關鍵字中聲明,在這個匿名函數裡也就不能獲取到它,所以開發中要注意這個問題。的變量,但我發現好像是不可以的:

<?php
//例一
//在函数里定义一个匿名函数,并且调用它
function printStr() {
  $func = function( $str ) {
    echo $str;
  };
  $func( &#39; hello my girlfriend ! &#39; );
}
printStr();//输出 hello my girlfriend !
//例二
//在函数中把匿名函数返回,并且调用它
function getPrintStrFunc() {
  $func = function( $str ) {
    echo $str;
  };
  return $func;
}
$printStrFunc = getPrintStrFunc();
$printStrFunc( &#39; do you love me ? &#39; );//输出 do you love me ?
//例三
//把匿名函数当做参数传递,并且调用它
function callFunc( $func ) {
  $func( &#39; no!i hate you &#39; );
}
$printStrFunc = function( $str ) {
  echo $str.&#39;<br>&#39;;
};
callFunc( $printStrFunc );
//也可以直接将匿名函数进行传递。如果你了解js,这种写法可能会很熟悉
callFunc( function( $str ) {
  echo $str; //输出no!i hate you
} );
登入後複製

額,原來use所引用的也只不過是變量的一個副本clone而已。要達到這個效果,其實在變數前面加上一個& 符號就可以了:

<?php
function getMoney() {
  $rmb = 1;
  $dollar = 8;
  $func = function() use ( $rmb ) {
    echo $rmb;
    echo $dollar;
  };
  $func();
}
getMoney();
//输出:1
登入後複製

好,這樣匿名函數就可以引用上下文的變數了。 use所引用的變量,而外界則不能得到這些變量,這樣形成'閉包'這個概念可能會更清晰一些。 #好吧,扯了這麼多,那麼如果我們要呼叫一個類別裡面的匿名函式呢?

綁定的概念

上面的範例的Closure只是全域的的匿名函數,好了,那我們現在要指定一個類別有一個匿名函數。 。定之後,就好像A中有這麼個函數一樣,但是這個函數是public還是private,bind的最後一個參數就說明了這個函數的可呼叫範圍。

上面大家看到了bindTo,我們來看官網的介紹

<?php
function getMoney() {
  $rmb = 1;
  $func = function() use ( $rmb ) {
    echo $rmb.&#39;<br>&#39;;
    //把$rmb的值加1
    $rmb++;
  };
  $func();
  echo $rmb;
}
getMoney();
//输出:
//1
//1
登入後複製

Closure::bind — 複製一個閉包,綁定指定的$this物件和類別作用域。

說明

public static Closure Closure::bind ( Closure $closure , object $newthis [, mixed $newscope = 'static' ] )

這個方法是

Closure: :bindTo

() 的靜態版本。查看它的文件以取得更多資訊。

參數

closure需要綁定的匿名函數。 newthis

需要綁定到匿名函數的對象,或 NULL 建立未綁定的閉包。

newscope

想要綁定給閉包的類別作用域,或是 'static' 表示不改變。如果傳入一個對象,則使用這個對象的型別名稱。 類別作用域用來決定在閉包中 $this 物件的 私有、保護方法 的可見性。 (備註:可以傳入類別名稱或類別的實例,預設值是'static', 表示不改變。)

傳回值:

傳回一個新的Closure 物件或在失敗時返回FALSE

<?php
function getMoney() {
  $rmb = 1;
  $func = function() use ( &$rmb ) {
    echo $rmb.&#39;<br>&#39;;
    //把$rmb的值加1
    $rmb++;
  };
  $func();
  echo $rmb;
}
getMoney();
//输出:
//1
//2
登入後複製

我們再來看個例子加深下理解:

<?php
function getMoneyFunc() {
  $rmb = 1;
  $func = function() use ( &$rmb ) {
    echo $rmb.&#39;<br>&#39;;
    //把$rmb的值加1
    $rmb++;
  };
  return $func;
}
$getMoney = getMoneyFunc();
$getMoney();
$getMoney();
$getMoney();
//输出:
//1
//2
//3
登入後複製

我們再看一個demo:

<?php
class A {
  public static function testA() {
    return function($i) { //返回匿名函数
      return $i+100;
    };
  }
}
function B(Closure $callback)
{
  return $callback(200);
}
$a = B(A::testA());
print_r($a);//输出 300
登入後複製

透過上面的幾個例子,其實匿名綁定的理解就不難了....我們在看一個擴充的demo(引入trait特性)

<?php
class A {
  public $base = 100;
}
class B {
  private $base = 1000;
}
$f = function () {
  return $this->base + 3;
};
$a = Closure::bind($f, new A);
print_r($a());//输出 103
echo PHP_EOL;
$b = Closure::bind($f, new B , &#39;B&#39;);
print_r($b());//输出1003
登入後複製
例如現在我們用現在購物環境
(PHP 5 >= 5.4.0, PHP 7)
登入後複製
補充說明:閉包可以使用USE關鍵連接外部變數。

總結:PHP閉包的特性其實用CLASS就可以實現類似甚至強大得多的功能,更不能和js的閉包相提並論了吧,只能期待PHP以後對

閉包支援

的改進。不過匿名函數還是挺有用的,例如在使用preg_replace_callback等之類的函數可以不用在外部宣告

回呼函數

了。合理使用閉包能讓程式碼更簡潔精煉。

以上是php 中的closure用法實例詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!