PHP中的匿名函數(shù)怎么實現(xiàn)?針對這個問題,這篇文章詳細(xì)介紹了相對應(yīng)的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。
站在用戶的角度思考問題,與客戶深入溝通,找到寬城網(wǎng)站設(shè)計與寬城網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗,讓設(shè)計與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個性化、用戶體驗好的作品,建站類型包括:成都網(wǎng)站制作、成都網(wǎng)站建設(shè)、外貿(mào)營銷網(wǎng)站建設(shè)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣、域名注冊、雅安服務(wù)器托管、企業(yè)郵箱。業(yè)務(wù)覆蓋寬城地區(qū)。
在匿名函數(shù)出現(xiàn)之前,所有的函數(shù)都需要先命名才能使用
function increment($value) { return $value + 1; } array_map('increment', [1, 2, 3]);
有的時候函數(shù)可能只需要使用一次,這時候使用匿名函數(shù)會使得代碼更加簡潔直觀,同時也避免了函數(shù)在其他地方被使用
array_map(function($value){ return $value + 1; }, [1, 2, 3]);
定義和使用
PHP 將閉包和匿名函數(shù)視為同等概念(本文統(tǒng)稱為匿名函數(shù)),本質(zhì)上都是偽裝成函數(shù)的對象。
匿名函數(shù)的本質(zhì)是對象,因此跟對象一樣可將匿名函數(shù)賦值給某一變量
$greet = function(string $name){ echo "hello {$name}"; } $greet("jack") // hello jack
所有的匿名函數(shù)都是 Closure 對象的實例
$greet instanceof Closure // true
對象并沒有什么父作用域可言,所以需要使用 use 來手動聲明使用的變量,
$num = 1; $func = function() use($num){ $num = $num + 1; echo $num; } $func(); // 2 echo $num; // 還是 1
如果要讓匿名函數(shù)中的變量生效,需要使用引用傳值
$num = 1; $func = function() use(&$num){ $num = $num + 1; echo $num; } $func(); // 2 echo $num; // 2
從 PHP 5.4 開始,在類里面使用匿名函數(shù)時,匿名函數(shù)的 $this 將自動綁定到當(dāng)前類
class Foo { public function bar() { return function() { return $this; }; } } $foo = new Foo(); $obj = $foo->bar(); // Closure() $obj(); // Foo
如果不想讓自動綁定生效,可使用靜態(tài)匿名函數(shù)
class Foo { public function bar() { return static function() { return $this; }; } } $foo = new Foo(); $obj = $foo->bar(); // Closure() $obj(); // Using $this when not in object context
匿名函數(shù)的本質(zhì)
匿名函數(shù)的本質(zhì)是 Closure 對象,包括了以下五個方法
Closure { private __construct ( void ) public static bind ( Closure $closure , object $newthis [, mixed $newscope = "static" ] ) : Closure public bindTo ( object $newthis [, mixed $newscope = "static" ] ) : Closure public call ( object $newthis [, mixed $... ] ) : mixed public static fromCallable ( callable $callable ) : Closure }
__construct - 防止匿名函數(shù)被實例化
$closure = new \Closure(); // PHP Error: Instantiation of 'Closure' is not allowed
Closure::bindTo - 復(fù)制當(dāng)前匿名函數(shù)對象,綁定指定的 $this 對象和類作用域。通俗的說,就是手動將匿名函數(shù)與指定對象綁定,利用這點,可以為擴(kuò)展對象的功能。
// 定義商品類 class Good { private $price; public function __construct(float $price) { $this->price = $price; } } // 定義一個匿名函數(shù),計算商品的促銷價 $addDiscount = function(float $discount = 0.8){ return $this->price * $discount; } $good = new Good(100); // 將匿名函數(shù)綁定到 $good 實例,同時指定作用域為 Good $count = $addDiscount->bindTo($good, Good::class); $count(); // 80 // 將匿名函數(shù)綁定到 $good 實例,但是不指定作用域,將無法訪問 $good 的私有屬性 $count = $addDiscount->bindTo($good); $count(); // 報錯
Closure::bind - bindTo 方法的靜態(tài)版本,有兩種用法:
用法一:實現(xiàn)與 bindTo 方法同樣的效果
$count = \Closure::bind($addDiscount, $good, Good::class);
用法二:將匿名函數(shù)與類(而不是對象)綁定,記得要將第二個參數(shù)設(shè)置為 null
// 商品庫存為 10 class Good { static $num = 10; } // 每次銷售后返回當(dāng)前庫存 $sell = static function() { return"當(dāng)前庫存為". --static::$num ; }; // 將靜態(tài)匿名函數(shù)綁定到 Good 類中 $sold = \Closure::bind($sell, null, Good::class); $sold(); // 當(dāng)前庫存為 9 $sold(); // 當(dāng)前庫存為 8
call - PHP 7 新增的 call 方法可以實現(xiàn)綁定并調(diào)用匿名函數(shù),除了語法更加簡潔外,性能也更高
// call 版本 $addDiscount->call($good, 0.5); // 綁定并傳入?yún)?shù) 0.5,結(jié)果為 50 // bindTo 版本 $count = $addDiscount->bindTo($good, Good::class, 0.5); $count(); // 50
fromCallable - 將給定的 callable 函數(shù)轉(zhuǎn)化成匿名函數(shù)
class Good { private $price; public function __construct(float $price) { $this->price = $price; } } function addDiscount(float $discount = 0.8){ return $this->price * $discount; } $closure = \Closure::fromCallable('addDiscount'); $good = new Good(100); $count = $closure->bindTo($good); $count = $closure->bindTo($good, Good::class); // 報錯,不能重復(fù)綁定作用域 $count(); // 報錯,無法訪問私有屬性
fromCallable 等價于
$reflexion = new ReflectionFunction('addDiscount'); $closure = $reflexion->getClosure();
這里有一點需要特別注意的是,無論是 fromCallable 轉(zhuǎn)化成的閉包,還是使用反射得到的閉包,在使用 bindTo 時,如果第二個參數(shù)指定綁定類,會報錯
Cannot rebind scope of closure created by ReflectionFunctionAbstract::getClosure()
關(guān)于PHP中的匿名函數(shù)怎么實現(xiàn)問題的解答就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道了解更多相關(guān)知識。
網(wǎng)頁名稱:PHP中的匿名函數(shù)怎么實現(xiàn)
網(wǎng)站地址:http://vcdvsql.cn/article12/gjepdc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供商城網(wǎng)站、軟件開發(fā)、關(guān)鍵詞優(yōu)化、做網(wǎng)站、移動網(wǎng)站建設(shè)、
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)