日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢(xún)
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
PHP中的匿名函數(shù)怎么實(shí)現(xiàn)-創(chuàng)新互聯(lián)

PHP中的匿名函數(shù)怎么實(shí)現(xiàn)?針對(duì)這個(gè)問(wèn)題,這篇文章詳細(xì)介紹了相對(duì)應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問(wèn)題的小伙伴找到更簡(jiǎn)單易行的方法。

創(chuàng)新互聯(lián)專(zhuān)注于企業(yè)網(wǎng)絡(luò)營(yíng)銷(xiāo)推廣、網(wǎng)站重做改版、明溪網(wǎng)站定制設(shè)計(jì)、自適應(yīng)品牌網(wǎng)站建設(shè)、H5開(kāi)發(fā)、商城網(wǎng)站開(kāi)發(fā)、集團(tuán)公司官網(wǎng)建設(shè)、外貿(mào)網(wǎng)站建設(shè)、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁(yè)設(shè)計(jì)等建站業(yè)務(wù),價(jià)格優(yōu)惠性?xún)r(jià)比高,為明溪等各大城市提供網(wǎng)站開(kāi)發(fā)制作服務(wù)。

在匿名函數(shù)出現(xiàn)之前,所有的函數(shù)都需要先命名才能使用

function increment($value)
{
    return $value + 1;
}
array_map('increment', [1, 2, 3]);

有的時(shí)候函數(shù)可能只需要使用一次,這時(shí)候使用匿名函數(shù)會(huì)使得代碼更加簡(jiǎn)潔直觀,同時(shí)也避免了函數(shù)在其他地方被使用

array_map(function($value){
    return $value + 1;
}, [1, 2, 3]);

定義和使用

PHP 將閉包和匿名函數(shù)視為同等概念(本文統(tǒng)稱(chēng)為匿名函數(shù)),本質(zhì)上都是偽裝成函數(shù)的對(duì)象。

匿名函數(shù)的本質(zhì)是對(duì)象,因此跟對(duì)象一樣可將匿名函數(shù)賦值給某一變量

$greet = function(string $name){
    echo "hello {$name}";
}
$greet("jack") // hello jack

所有的匿名函數(shù)都是 Closure 對(duì)象的實(shí)例

$greet instanceof Closure // true

對(duì)象并沒(méi)有什么父作用域可言,所以需要使用 use 來(lái)手動(dòng)聲明使用的變量,

$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 開(kāi)始,在類(lèi)里面使用匿名函數(shù)時(shí),匿名函數(shù)的 $this 將自動(dòng)綁定到當(dāng)前類(lèi)

class Foo {
    public function bar()
    {   
        return function() {
            return $this;
        };
    }
}
$foo = new Foo();
$obj = $foo->bar(); // Closure()
$obj();   // Foo

如果不想讓自動(dòng)綁定生效,可使用靜態(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 對(duì)象,包括了以下五個(gè)方法

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ù)被實(shí)例化

$closure = new \Closure();
// PHP Error:  Instantiation of 'Closure' is not allowed

Closure::bindTo - 復(fù)制當(dāng)前匿名函數(shù)對(duì)象,綁定指定的 $this 對(duì)象和類(lèi)作用域。通俗的說(shuō),就是手動(dòng)將匿名函數(shù)與指定對(duì)象綁定,利用這點(diǎn),可以為擴(kuò)展對(duì)象的功能。

// 定義商品類(lèi)
class Good {
    private $price;
    public function __construct(float $price)
    {
        $this->price = $price;
    }
}
// 定義一個(gè)匿名函數(shù),計(jì)算商品的促銷(xiāo)價(jià)
$addDiscount = function(float $discount = 0.8){
    return $this->price * $discount;
}
$good = new Good(100);
// 將匿名函數(shù)綁定到 $good 實(shí)例,同時(shí)指定作用域?yàn)?Good
$count = $addDiscount->bindTo($good, Good::class); 
$count(); // 80
// 將匿名函數(shù)綁定到 $good 實(shí)例,但是不指定作用域,將無(wú)法訪問(wèn) $good 的私有屬性
$count = $addDiscount->bindTo($good); 
$count(); // 報(bào)錯(cuò)

Closure::bind - bindTo 方法的靜態(tài)版本,有兩種用法:

用法一:實(shí)現(xiàn)與 bindTo 方法同樣的效果

$count = \Closure::bind($addDiscount, $good, Good::class);

用法二:將匿名函數(shù)與類(lèi)(而不是對(duì)象)綁定,記得要將第二個(gè)參數(shù)設(shè)置為 null

// 商品庫(kù)存為 10
class Good {
    static $num = 10;
}
// 每次銷(xiāo)售后返回當(dāng)前庫(kù)存
$sell = static function() {
    return"當(dāng)前庫(kù)存為". --static::$num ;
};
// 將靜態(tài)匿名函數(shù)綁定到 Good 類(lèi)中
$sold = \Closure::bind($sell, null, Good::class);
$sold(); // 當(dāng)前庫(kù)存為 9
$sold(); // 當(dāng)前庫(kù)存為 8

call - PHP 7 新增的 call 方法可以實(shí)現(xiàn)綁定并調(diào)用匿名函數(shù),除了語(yǔ)法更加簡(jiǎn)潔外,性能也更高

// 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);   // 報(bào)錯(cuò),不能重復(fù)綁定作用域
$count(); // 報(bào)錯(cuò),無(wú)法訪問(wèn)私有屬性

fromCallable 等價(jià)于

$reflexion = new ReflectionFunction('addDiscount');
$closure = $reflexion->getClosure();

這里有一點(diǎn)需要特別注意的是,無(wú)論是 fromCallable 轉(zhuǎn)化成的閉包,還是使用反射得到的閉包,在使用 bindTo 時(shí),如果第二個(gè)參數(shù)指定綁定類(lèi),會(huì)報(bào)錯(cuò)

Cannot rebind scope of closure created by ReflectionFunctionAbstract::getClosure()

關(guān)于PHP中的匿名函數(shù)怎么實(shí)現(xiàn)問(wèn)題的解答就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,如果你還有很多疑惑沒(méi)有解開(kāi),可以關(guān)注創(chuàng)新互聯(lián)成都網(wǎng)站設(shè)計(jì)公司行業(yè)資訊頻道了解更多相關(guān)知識(shí)。

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無(wú)理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性?xún)r(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專(zhuān)為企業(yè)上云打造定制,能夠滿(mǎn)足用戶(hù)豐富、多元化的應(yīng)用場(chǎng)景需求。


當(dāng)前題目:PHP中的匿名函數(shù)怎么實(shí)現(xiàn)-創(chuàng)新互聯(lián)
分享地址:http://www.dlmjj.cn/article/ccciod.html