首頁  >  文章  >  後端開發  >  PHP 閉包詳解及實例程式碼

PHP 閉包詳解及實例程式碼

高洛峰
高洛峰原創
2016-12-30 13:51:42927瀏覽

閉包和匿名函數在PHP5.3.0中引入的。

閉包是指:創建時封裝周圍狀態的函數。即使閉包所處的環境不存在了,閉包中封裝的狀態依然存在。

理論上,閉包和匿名函數是不同的概念。但是PHP將其視為相同概念。

實際上,閉包和匿名函數是偽裝成函數的物件。他們是Closure類別的實例。

閉包和字串、整數一樣,是一等值型別。

創建閉包

<?php
$clousre = function ($name) {
return &#39;Hello &#39; . $name;
};
echo $closure(&#39;nesfo&#39;);

我們之所以能調用$closure變量,是因為這個變量的值是一個閉包,而且閉包對象實現了__invoke()魔術方法。只要變數名後有(),PHP就會找並呼叫__invoke()方法。通常會把PHP閉包當成函數的回調使用。 array_map(), preg_replace_callback()方法都會用到回呼函數,這是使用閉包的最佳時機!

舉個例子:

<?php
$numbersPlusOne = array_map(function ($number) {
return $number + 1;
}, [1, 2, 3]);
print_r($numbersPlusOne);

得到結果:

[2, 3, 4]

在閉包出現之前,只能單獨建立具名函數,然後使用名稱來引用那個函數。這麼做,程式碼執行會稍微慢一點,而且把回呼的實作和使用場景隔離了。

<?php
function incrementNum ($number) {
return $number + 1;
}
$numbersPlusOne = array_map(&#39;incrementNum&#39;, [1, 2, 3]);
print_r($numbersPlusOne);

附加狀態

匿名函數不只可以當回調使用,還可以為PHP附加並封裝狀態。

PHP中,必須手動呼叫閉包物件的bindTo()方法或使用use關鍵字,才能把狀態附加到PHP閉包上。

<?php
function enclosePerson ($name) {
return function ($doCommand) use ($name) {
return $name . &#39;, &#39; . $doCommand;
}
}
$clay = enclosePerson(&#39;Clay&#39;);
echo $clay(&#39;get me sweet tea!&#39;);

得到結果:

"Clay, get me sweet tea!"

PHP閉包是對象,每個閉包實例都可以使用$this關鍵字取得閉包的內部狀態。閉包物件的預設狀態沒什麼用,只有__invoke()方法和bindTo方法而已。

我們可以使用bindTo()這個方法,將Closure物件的內部狀態綁定到其它物件上。

bindTo()方法的第二個參數:其作用是指定綁定閉包的那個物件所屬的PHP類別。因此,閉包可以存取綁定閉包的物件中受保護和私有的成員。

PHP框架經常使用bindTo()方法把路由URL映射到匿名回呼函數上。這麼做可以在這個匿名函數中使用$this關鍵字引用重要的應用程式物件。

使用bindTo()方法附加閉包狀態

<?php
class App
{
protected $routes = [];
protected $responseStatus = &#39;200 OK&#39;;
protected $responseContentType = &#39;text/html&#39;;
protected $responseBody = &#39;Hello world&#39;;
public function addRoute($routePath, $routeCallback){
$this->routes[$routePath] = $routeCallback->bindTo($this, __CLASS__);
}
public function dispatch($currentPath){
foreach($this->routes as $routePath => $callback){
if ($routePath === $currentPath) {
$callback();
}
}
header(&#39;HTTP/1.1&#39; . $this->responseStatus);
header(&#39;Content-type: &#39; . $this->responseContentType);
header(&#39;Content-length&#39; . mb_strlen($this->responseBody));
echo $this->responseBody;
}
}
<br>
<?php
$app = new App();
$app->addRoute(&#39;/user/nesfo&#39;, function () {
$this->responseContentType = &#39;application/json; charset=utf8&#39;;
$this->responseBody = &#39;{"name": "nesfo"}&#39;;
});
$app->dispatch(&#39;/user/nesfo&#39;);

以上就是對PHP 閉包資料的資料整理,後續繼續補充相關資料謝謝大家對本站的支持!

更多PHP 閉包詳解及實例代碼相關文章請關注PHP中文網!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn