淺析PHP中的閉包和匿名函數(shù)
閉包是指在創(chuàng)建時(shí)封裝周圍狀態(tài)的函數(shù)。即使閉包所在的環(huán)境不存在了,閉包中封裝的狀態(tài)依然存在。
匿名函數(shù)就是沒有名稱的函數(shù)。匿名函數(shù)可以賦值給變量,還能像其他任何PHP對象那樣傳遞。不過匿名函數(shù)仍是函數(shù),因此可以調(diào)用,還可以傳入?yún)?shù)。匿名函數(shù)特別適合作為函數(shù)或方法的回調(diào)。
注意:理論上講,閉包和匿名函數(shù)是不同的概念。不過,PHP將其視作相同的概念。所以,我們提到閉包時(shí),指的也是匿名函數(shù),反之亦然。
PHP閉包和匿名函數(shù)使用的句法與普通函數(shù)相同,但閉包和匿名函數(shù)其實(shí)是 偽裝成函數(shù)的對象(Closure類的實(shí)例) 。
創(chuàng)建閉包
$closure = function($name){ return sprintf("Hello %s", $name); } echo $closure("jerry"); // 檢測$closure變量是否是一個(gè)閉包 var_dump($closure instanceof Closure);
以上代碼創(chuàng)建了一個(gè)閉包對象,然后將其賦值給 $closure 變量。閉包和普通的PHP函數(shù)很像,使用的句法相同,也接收參數(shù),而且能返回值。
說明:我們之所以能夠調(diào)用 $closure 變量,是因?yàn)檫@個(gè)變量的值是一個(gè)閉包,而且閉包對象實(shí)現(xiàn)了 __invoke() 魔術(shù)方法。只要變量名后有 () ,PHP就會(huì)查找并調(diào)用 __invoke()
方法。
使用閉包
我們通常把PHP閉包當(dāng)做當(dāng)做函數(shù)和方法的回調(diào)使用。很多PHP函數(shù)都會(huì)用到回調(diào)函數(shù),例如 array_map()
和 preg_replace_callback()
.如下示例,我們將用 array_map() 處理數(shù)組,將數(shù)組每一項(xiàng)自增1:
$nubmers = array_map(function($number){ return $number++; }, [1,2,3]); var_dump($numbers);
附加狀態(tài)
PHP閉包不會(huì)像真正的javascrypt閉包那樣自動(dòng)封裝應(yīng)用的狀態(tài),我們必須手動(dòng)調(diào)用閉包對象的 bindTo() 方法或者使用 use 關(guān)鍵字,把狀態(tài)附加到PHP閉包上。
使用 use 關(guān)鍵字
使用 use 關(guān)鍵字來附加閉包狀態(tài)更加常見,因此我們先來看這種方式。使用 use 關(guān)鍵字把變量附加閉包上時(shí),附加的變量會(huì)記住附加時(shí)賦給它的值。
function Car ($name){ return function($statu)use($name){ return sprintf("Car %s is %s", $name, $statu); } } // 將車名封裝在閉包中 $car = Car("bmw"); // 調(diào)用車的動(dòng)作 // 輸出--> "bmw is running" echo $car("running");
注意:使用 use 關(guān)鍵字可以把多個(gè)參數(shù)傳入閉包,此時(shí)要像PHP函數(shù)或方法的參數(shù)一樣,使用逗號分隔多個(gè)參數(shù)。
使用 bindTo() 方法附加閉包的狀態(tài)
與其它PHP對象類似,每個(gè)閉包實(shí)例都可以使用 $this 關(guān)鍵字獲取閉包的內(nèi)部狀態(tài)。閉包對象的默認(rèn)狀態(tài)沒什么用,不過有一個(gè) __invoke() 魔術(shù)方法和 bindTo() 方法。
bindTo() 方法為閉包增加了一些有趣的潛力。我們可以使用這個(gè)方法把 Closure 對象的內(nèi)部狀態(tài)綁定到其它對象上。
bindTo() 方法的第二個(gè)參數(shù)很重要,其作用是指定綁定閉包的那個(gè)對象所屬的PHP類。因此,閉包可以訪問綁定閉包的對象中受保護(hù)和私有的成員變量。
class TestClosure { private $name=[]; private $age; private $sex; public function addPerson($name, $personCallback){ // 將閉包對象綁定當(dāng)前實(shí)例 $this->name[$name] = $personCallback->bindTo($this, __CLASS__); } public function display($name){ foreach ($this->name as $key => $callback){ if($key == $name){ // 執(zhí)行閉包對象,將閉包狀態(tài)附加到類 $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 */
總結(jié)
以上所述是小編給大家介紹的PHP中的閉包和匿名函數(shù),希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
- 詳解PHP中instanceof關(guān)鍵字及instanceof關(guān)鍵字有什么作用
- php中instanceof 與 is_a()區(qū)別分析
- PHP 面向?qū)ο蟪绦蛟O(shè)計(jì)(oop)學(xué)習(xí)筆記(一) - 抽象類、對象接口、instanceof 和契約式編程
- php的閉包(Closure)匿名函數(shù)初探
- php的閉包(Closure)匿名函數(shù)詳解
- PHP閉包(Closure)使用詳解
- PHP中的閉包(匿名函數(shù))淺析
- PHP閉包實(shí)例解析
- PHP 閉包詳解及實(shí)例代碼
- php的instanceof和判斷閉包Closure操作示例
相關(guān)文章
thinkphp5 + ajax 使用formdata提交數(shù)據(jù)(包括文件上傳) 后臺返回json完整實(shí)例
這篇文章主要介紹了thinkphp5 + ajax 使用formdata提交數(shù)據(jù)(包括文件上傳) 后臺返回json操作,結(jié)合實(shí)例形式分析了thinkphp5 + ajax 使用formdata提交數(shù)據(jù)、文件上傳與后臺返回json遇到的相關(guān)問題即解決方法,需要的朋友可以參考下2020-03-03Swoole4.4協(xié)程搶占式調(diào)度器詳解
這篇文章主要介紹了Swoole4.4協(xié)程搶占式調(diào)度器詳解,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-05-05Laravel框架學(xué)習(xí)筆記之批量更新數(shù)據(jù)功能
這篇文章主要介紹了Laravel框架學(xué)習(xí)筆記之批量更新數(shù)據(jù)功能,結(jié)合實(shí)例形式分析了Laravel框架批量更新數(shù)據(jù)的相關(guān)模型定義與使用操作技巧,需要的朋友可以參考下2019-05-05基于php實(shí)現(xiàn)七牛抓取遠(yuǎn)程圖片
由于公司網(wǎng)站之前的用戶頭像都是存儲(chǔ)在自己的服務(wù)器上的,后來感覺管理不方便,新增加的用戶頭像都上傳到了七牛,為了方便統(tǒng)一管理,領(lǐng)導(dǎo)說把本地服務(wù)器的頭像全部遷移到了七牛2015-12-12PHP使用GIFEncoder類生成的GIF動(dòng)態(tài)圖片驗(yàn)證碼
這篇文章主要介紹了PHP使用GIFEncoder類生成的GIF動(dòng)態(tài)圖片驗(yàn)證碼,文中附帶GIFEncoder類源碼,需要的朋友可以參考下2014-07-07