PHP如何使用Closure創(chuàng)建匿名函數(shù)-創(chuàng)新互聯(lián)

這篇文章將為大家詳細(xì)講解有關(guān)PHP如何使用Closure創(chuàng)建匿名函數(shù),文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個(gè)參考,希望大家閱讀完這篇文章后對相關(guān)知識有一定的了解。

成都創(chuàng)新互聯(lián)企業(yè)建站,十年網(wǎng)站建設(shè)經(jīng)驗(yàn),專注于網(wǎng)站建設(shè)技術(shù),精于網(wǎng)頁設(shè)計(jì),有多年建站和網(wǎng)站代運(yùn)營經(jīng)驗(yàn),設(shè)計(jì)師為客戶打造網(wǎng)絡(luò)企業(yè)風(fēng)格,提供周到的建站售前咨詢和貼心的售后服務(wù)。對于成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站建設(shè)中不同領(lǐng)域進(jìn)行深入了解和探索,創(chuàng)新互聯(lián)在網(wǎng)站建設(shè)中充分了解客戶行業(yè)的需求,以靈動的思維在網(wǎng)頁中充分展現(xiàn),通過對客戶行業(yè)精準(zhǔn)市場調(diào)研,為客戶提供的解決方案。

Closure 類

用于代表匿名函數(shù)的類。

匿名函數(shù)(在 PHP 5.3 中被引入)會產(chǎn)生這個(gè)類型的對象。在過去,這個(gè)類被認(rèn)為是一個(gè)實(shí)現(xiàn)細(xì)節(jié),但現(xiàn)在可以依賴它做一些事情。自 PHP 5.4 起,這個(gè)類帶有一些方法,允許在匿名函數(shù)創(chuàng)建后對其進(jìn)行更多的控制。

這個(gè)類不能實(shí)例化,里面主要有兩個(gè)方法,都用來復(fù)制閉包,一個(gè)靜態(tài)一個(gè)動態(tài),下面分別詳細(xì)講解下這兩個(gè)不好理解的方法。

Closure::bind

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

參數(shù)說明:

  • closure需要綁定的匿名函數(shù)。

  • newthis需要綁定到匿名函數(shù)的對象,或者 NULL 創(chuàng)建未綁定的閉包。

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

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.

上面是該方法的定義,

第一個(gè)參數(shù)很好理解,就是一個(gè)閉包函數(shù);

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

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

例子

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

上面的代碼會報(bào)錯(cuò)Fatal error: Uncaught Error: Call to protected method T::who() from  context 'Closure'。 加上bind第三個(gè)參數(shù)為t::class或者new T(),會正常輸出每一個(gè)結(jié)果。

我是T里面的保護(hù)函數(shù):who我是T里面的公共函數(shù):name我是T里面的私有函數(shù):show

當(dāng)然了,閉包也可以傳遞參數(shù)

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

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

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

另外還有個(gè)特別要說明的例子

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

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

Closure::bindTo

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

例子

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

上面函數(shù)的輸出和bind的類似

我是T里面的私有函數(shù):show我是T里面的保護(hù)函數(shù):who我是T里面的公共函數(shù):name

一個(gè)trick

這個(gè)函數(shù)是在看composer生成的自動加載源碼的時(shí)候碰到的,在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中,第一感覺是傳錯(cuò)參數(shù)了,其實(shí)不然,這里調(diào)用了一個(gè)函數(shù),這個(gè)函數(shù)會返回一個(gè)Closure對象,
也就是一個(gè)匿名函數(shù),最終傳入的參數(shù)還是一個(gè)callable類型。再看看這個(gè)返回的閉包,里面使用了use,這是連接閉包和外部變量的橋梁。
至于這里為什么普通傳參數(shù)就可以,是因?yàn)閜hp5里面,對象形參和實(shí)參數(shù)指向相同的對象,函數(shù)里面對對象的修改會反映到對象外面。

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

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);}

總結(jié)

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

關(guān)于PHP如何使用Closure創(chuàng)建匿名函數(shù)就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。

分享題目:PHP如何使用Closure創(chuàng)建匿名函數(shù)-創(chuàng)新互聯(lián)
文章URL:http://bm7419.com/article16/igpdg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供動態(tài)網(wǎng)站ChatGPT、網(wǎng)站內(nèi)鏈、電子商務(wù)品牌網(wǎng)站建設(shè)、品牌網(wǎng)站設(shè)計(jì)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站托管運(yùn)營