您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關(guān)PHP+Swoole的閉包怎么寫(xiě)的內(nèi)容。小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧。
JS程序員總是嘲笑PHP沒(méi)有閉包,今天抽空寫(xiě)一篇文章來(lái)專門(mén)介紹一下PHP的閉包。從5.3版本開(kāi)始PHP就增加了匿名函數(shù)支持,經(jīng)過(guò)數(shù)個(gè)版本迭代到現(xiàn)在的PHP5.6、PHP7,PHP語(yǔ)言的閉包已經(jīng)非常完善了。再結(jié)合Swoole提供的事件驅(qū)動(dòng)支持,PHP的閉包功能非常強(qiáng)大而且很優(yōu)雅。
匿名函數(shù)是閉包的核心,匿名函數(shù)在PHP里實(shí)際上是一個(gè)Closure類的對(duì)象(請(qǐng)注意是對(duì)象)。與普通的面向?qū)ο缶幊谭绞讲煌?,匿名函?shù)的代碼是直接寫(xiě)在調(diào)用處的,不需要額外寫(xiě)一個(gè)類,編寫(xiě)方法的代碼。這樣的好處就是更直接。下面的示例是設(shè)置一個(gè)定時(shí)器,每2秒輸出hello world。
傳統(tǒng)寫(xiě)法
function timer () { echo "hello world"; } Swoole\Timer::tick(2000, 'timer');
閉包寫(xiě)法
Swoole\Timer::tick(2000, function () { echo "hello world"; });
非閉包的傳統(tǒng)寫(xiě)法,先要聲明一個(gè)函數(shù),再轉(zhuǎn)入函數(shù)名稱字符串。兩段代碼是分離的,不夠直觀。而閉包的寫(xiě)法把定時(shí)器的聲明和定時(shí)器要執(zhí)行的代碼寫(xiě)在了一起,邏輯非常清晰直觀。使用閉包語(yǔ)法可以很方便編寫(xiě)回調(diào)函數(shù)。在事件驅(qū)動(dòng)編程、排序、array_walk等需要用戶傳入一段執(zhí)行代碼的場(chǎng)景中,閉包的寫(xiě)法非常優(yōu)雅。
閉包更強(qiáng)大的地方在于它可以直接在調(diào)用處引入外部變量。PHP中實(shí)現(xiàn)的方法就是use關(guān)鍵詞。
如果剛才的定時(shí)器需要傳入一個(gè)變量,傳統(tǒng)的寫(xiě)法只能通過(guò)全局變量來(lái)實(shí)現(xiàn)。與JS不同,PHP的變量引入是顯式的,如果要引用外部變量必須使用use來(lái)聲明。而JS是隱式的,匿名函數(shù)內(nèi)部可以隨意操作外部變量,無(wú)需聲明。這樣好處是少寫(xiě)了一點(diǎn)代碼,缺點(diǎn)是存在風(fēng)險(xiǎn)和混亂。
傳統(tǒng)寫(xiě)法
$str = "hello world"; function timer () { global $str; echo $str; } Swoole\Timer::tick(2000, 'timer');
閉包寫(xiě)法
$str = "hello world"; Swoole\Timer::tick(2000, function () use ($str) { echo $str; });
閉包寫(xiě)法使用use直接引入了當(dāng)前的$str變量,而不需要使用global全局變量。另外如果是在swoole的事件驅(qū)動(dòng)編程模式,使用global就無(wú)法實(shí)現(xiàn)異步并發(fā)了,因?yàn)間lobal全局變量只有1個(gè),如果同時(shí)有多個(gè)客戶端請(qǐng)求,每個(gè)請(qǐng)求要查詢數(shù)據(jù)庫(kù),輸出不同的內(nèi)容,傳統(tǒng)的編程方法就不太容易實(shí)現(xiàn),需要使用全局變量數(shù)組,以客戶端的ID為KEY保存各自的數(shù)據(jù)。
傳統(tǒng)寫(xiě)法
$requestArray = array(); $dbResultArray = array(); function my_request($request, $response) { global $dbResultArray, $requestArray; $queryId = $db->query($sql, 'get_result'); $requestArray[$request->fd] = array($request, $response); $dbResultArray[$queryId] = $request->fd; } function get_result($queryId, $queryResult) { global $dbResultArray, $requestArray; list($request, $response) = $requestArray[$dbResultArray[$queryId]]; $response->end($queryResult); } $server->on('request', 'my_request');
閉包寫(xiě)法
$server->on('request', function ($request, $response) { $queryId = $db->query($sql, function ($queryId, $queryResult) use ($request, $response) { $response->end($queryResult); }); });
傳統(tǒng)的寫(xiě)法非常復(fù)雜,需要反復(fù)多次從全局?jǐn)?shù)組保存/提取數(shù)據(jù)。而閉包的寫(xiě)法非常簡(jiǎn)潔優(yōu)雅,只用了幾行代碼就實(shí)現(xiàn)了同樣的功能。閉包寫(xiě)法非常適合用來(lái)編寫(xiě)異步非阻塞回調(diào)模式的服務(wù)器程序。目前熱門(mén)的編程語(yǔ)言中只有PHP和JS具備這種能力。
在類的方法中使用匿名函數(shù),5.4以上的版本無(wú)需使用use引入$this,直接可以在匿名函數(shù)中使用$this來(lái)調(diào)用當(dāng)前對(duì)象的方法。在swoole編程中,可以利用此特性減少$serv對(duì)象的use引入傳遞。
class Server extends Swoole\Server { function onReceive($serv, $fd, $reactorId, $data) { $db->query($sql, function ($queryId, $queryResult) use ($fd) { $this->send($fd, $queryResult); } } }
另外如果希望在閉包函數(shù)中修改外部變量,可以在use時(shí)為變量增加&引用符號(hào)即可。注意對(duì)象類型不需要加&,因?yàn)樵赑HP中對(duì)象默認(rèn)就是傳引用而非傳值。
感謝各位的閱讀!關(guān)于PHP+Swoole的閉包怎么寫(xiě)就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,讓大家可以學(xué)到更多知識(shí)。如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。