中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

PHP如何使用Closure創建匿名函數

發布時間:2020-07-30 10:08:55 來源:億速云 閱讀:163 作者:Leah 欄目:編程語言

這篇文章將為大家詳細講解有關PHP如何使用Closure創建匿名函數,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。

Closure 類

用于代表匿名函數的類。

匿名函數(在 PHP 5.3 中被引入)會產生這個類型的對象。在過去,這個類被認為是一個實現細節,但現在可以依賴它做一些事情。自 PHP 5.4 起,這個類帶有一些方法,允許在匿名函數創建后對其進行更多的控制。

這個類不能實例化,里面主要有兩個方法,都用來復制閉包,一個靜態一個動態,下面分別詳細講解下這兩個不好理解的方法。

Closure::bind

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

參數說明:

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

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

  • newscope想要綁定給閉包的類作用域,或者 'static' 表示不改變。如果傳入一個對象,則使用這個對象的類型名。 類作用域用來決定在閉包中 $this 對象的 私有、保護方法 的可見性。

The class scope to which associate the closure is to be associated, or 'static' to keep the

current one. If an object is given, the type of the object will be used instead. This determines the visibility of

protected and private methods of the bound object.

上面是該方法的定義,

第一個參數很好理解,就是一個閉包函數;

第二個參數就不太好理解,如果要復制的閉包中包含$this,這個對象就表示這個$this,閉包函數里面對這個對象的修改在調用結束之后也會保持一致,比如修改了一個屬性;

第三個參數就不太好理解了,看官方的說明也是云里霧里的,默認參數情況下,調用$this->訪問object $newthis中的屬性函數的時候,會有限制,只能訪問public屬性的函數,如果想訪問protected/private屬性,就要設置為對應的類名/類實例,就要像在類里面一樣,要訪問那個類的保護/私有屬性函數。

例子

<?phpclass T {    private function show()    {        echo "我是T里面的私有函數:show\n";    }    protected  function who()    {        echo "我是T里面的保護函數:who\n";    }    public function name()    {        echo "我是T里面的公共函數:name\n";    }}$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() from  context 'Closure'。 加上bind第三個參數為t::class或者new T(),會正常輸出每一個結果。

我是T里面的保護函數:who我是T里面的公共函數:name我是T里面的私有函數:show

當然了,閉包也可以傳遞參數

$test = new StdClass();var_dump($test);$func = Closure::bind(function($obj){    $obj->name = "燕睿濤";}, null);$func($test);var_dump($test);

上面的程序跟匿名函數一樣,啥對象也沒有依賴,上面的程序會輸出:

object(stdClass)#1 (0) {}object(stdClass)#1 (1) {  ["name"]=>  string(9) "燕睿濤"}

另外還有個特別要說明的例子

<?phpclass T {    private function show()    {        echo "我是T里面的私有函數:show\n";    }    protected  function who()    {        echo "我是T里面的保護函數:who\n";    }    public function name()    {        echo "我是T里面的公共函數:name\n";    }}$func = Closure::bind(function ($obj) {    $obj->show();}, null);$test = new T();$func($test);

上面的情況會輸出什么呢,沒錯,會報錯,提示訪問不了私有屬性show,這個時候,加上第三個參數就可以了,看了第三個參數不光影響$this的作用域,
也可以影響參數的作用域。

Closure::bindTo

bindTobind功能類似,這里只是另外一種形式,都是復制當前閉包對象,綁定指定的$this對象和類作用域。,參數比bind少了第一個,
后面兩個一樣,當然還有一個區別就是bindTo不是靜態方法,是閉包才會存在的一個屬性方法。

例子

<?phpclass T {    private function show()    {        echo "我是T里面的私有函數:show\n";    }    protected  function who()    {        echo "我是T里面的保護函數:who\n";    }    public function name()    {        echo "我是T里面的公共函數:name\n";    }}$func = function () {    $this->show();    $this->who();    $this->name();};$funcNew = $func->bindTo(new T(), T::class);$funcNew();

上面函數的輸出和bind的類似

我是T里面的私有函數:show我是T里面的保護函數:who我是T里面的公共函數:name

一個trick

這個函數是在看composer生成的自動加載源碼的時候碰到的,在composer中用的比較特別,下面是截取部分composer中的代碼

// 文件autoload_real.phpcall_user_func(\Composer\Autoload\ComposerStaticInit898ad46cb49e20577400c63254121bac::getInitializer($loader));// 文件autoload_static.phppublic static function getInitializer(ClassLoader $loader){    return \Closure::bind(function () use ($loader) {        $loader->prefixLengthsPsr4 = ComposerStaticInit25885cdf386fdaafc0bce14bb5a7d06e::$prefixLengthsPsr4;        $loader->prefixDirsPsr4 = ComposerStaticInit25885cdf386fdaafc0bce14bb5a7d06e::$prefixDirsPsr4;        $loader->prefixesPsr0 = ComposerStaticInit25885cdf386fdaafc0bce14bb5a7d06e::$prefixesPsr0;        $loader->classMap = ComposerStaticInit25885cdf386fdaafc0bce14bb5a7d06e::$classMap;    }, null, ClassLoader::class);}

上面的代碼比較奇特,在call_user_func中,第一感覺是傳錯參數了,其實不然,這里調用了一個函數,這個函數會返回一個Closure對象,
也就是一個匿名函數,最終傳入的參數還是一個callable類型。再看看這個返回的閉包,里面使用了use,這是連接閉包和外部變量的橋梁。
至于這里為什么普通傳參數就可以,是因為php5里面,對象形參和實參數指向相同的對象,函數里面對對象的修改會反映到對象外面。

所以,上面這么做是沒問題的,還有另外一種形式也可以

call_user_func(\Composer\Autoload\ComposerStaticInit898ad46cb49e20577400c63254121bac::getInitializer(), $loader);public static function getInitializer(){    return \Closure::bind(function ($loader) {        $loader->prefixLengthsPsr4 = ComposerStaticInit25885cdf386fdaafc0bce14bb5a7d06e::$prefixLengthsPsr4;        $loader->prefixDirsPsr4 = ComposerStaticInit25885cdf386fdaafc0bce14bb5a7d06e::$prefixDirsPsr4;        $loader->prefixesPsr0 = ComposerStaticInit25885cdf386fdaafc0bce14bb5a7d06e::$prefixesPsr0;        $loader->classMap = ComposerStaticInit25885cdf386fdaafc0bce14bb5a7d06e::$classMap;    }, null, ClassLoader::class);}

總結

好長時間沒寫blog了,有時候太煩躁,靜不下心來,有時又有沒有找到想寫的東西。還是得靜下心來,好好做好每一件事,遇事情不要煩躁,心放大,心平氣和的處理每一件事。

關于PHP如何使用Closure創建匿名函數就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

邵阳市| 通河县| 元谋县| 招远市| 固始县| 石棉县| 合阳县| 福泉市| 科技| 隆安县| 惠东县| 乐安县| 紫金县| 靖安县| 潼关县| 郴州市| 定西市| 正阳县| 鄯善县| 康平县| 册亨县| 湾仔区| 凌海市| 西林县| 大厂| 正镶白旗| 肇庆市| 桂林市| 阳信县| 宁明县| 阳东县| 花垣县| 揭东县| 宜阳县| 汤原县| 长岭县| 沅陵县| 枞阳县| 乌鲁木齐市| 新余市| 芮城县|