Closure 類別
#用來代表匿名函數的類別。
匿名函數(在 PHP 5.3 中被引入)會產生這個類型的物件。在過去,這個類別被認為是實作細節,但現在可以依賴它做一些事情。自 PHP 5.4 起,這個類別帶有一些方法,允許在匿名函數創建後對其進行更多的控制。
這個類別不能實例化,裡面主要有兩個方法,都用來複製閉包,一個靜態一個動態,下面分別詳細講解下這兩個不好理解的方法。
Closure::bind
public static Closure Closure::bind ( Closure $closure , object $newthis [, mixed $newscope = 'static' ] ) 参数说明: closure 需要绑定的匿名函数。 newthis 需要绑定到匿名函数的对象,或者 NULL 创建未绑定的闭包。 newscope 想要绑定给闭包的类作用域,或者 'static' 表示不改变。如果传入一个对象,则使用这个对象的类型名。 类作用域用来决定在闭包中 $this 对象的 私有、保护方法 的可见性。 The class scope to which associate the closure is to be associated, or 'static' to keep the current one. If an object is given, the type of the object will be used instead. This determines the visibility of protected and private methods of the bound object.
參數說明:
closure需要綁定的匿名函數。
newthis需要綁定到匿名函數的對象,或 NULL 建立未綁定的閉包。
newscope想要綁定給閉包的類別作用域,或是 'static' 表示不改變。如果傳入一個對象,則使用這個對象的型別名稱。類別作用域用來決定在閉包中 $this 物件的 私有、保護方法 的可見性。
The class scope to which associate the closure is to be associated, or 'static' to keep the
current one. If an object is given, the type of the object will be used instead. This determines the visibility of
protected and private methods of the bound object.
上面是該方法的定義,
第一個參數很好理解,就是一個閉包函數;
第二個參數就不太好理解,如果要複製的閉包中包含$this
,這個物件就表示這個$this
,閉包函數裡面對這個物件的修改在呼叫結束之後也會保持一致,例如修改了一個屬性;
第三個參數就不太好理解了,看官方的說明也是雲裡霧裡的,預設參數情況下,呼叫$this->
訪問object $newthis
中的屬性函數的時候,會有限制,只能存取public
屬性的函數,如果想存取protected/private
屬性,就要設定為對應的類別名稱/類別實例,就要像在類別裡面一樣,要存取那個類別的保護/私有屬性函數。
範例
<?php class T { private function show() { echo "我是T里面的私有函数:show\n"; } protected function who() { echo "我是T里面的保护函数:who\n"; } public function name() { echo "我是T里面的公共函数:name\n"; } } $test = new T(); $func = Closure::bind(function(){ $this->who(); $this->name(); $this->show(); }, $test); $func();
上面的程式碼會報錯Fatal error: Uncaught Error: Call to protected method T::who() from context 'Closure'
。加上bind第三個參數為t::class
或new T()
,會正常輸出每一個結果。
我是T里面的保护函数:who 我是T里面的公共函数:name 我是T里面的私有函数:show
當然了,閉包也可以傳遞參數
$test = new StdClass(); var_dump($test); $func = Closure::bind(function($obj){ $obj->name = "燕睿涛"; }, null); $func($test); var_dump($test);
上面的程式跟匿名函數一樣,啥物件也沒有依賴,上面的程式會輸出:
object(stdClass)#1 (0) { } object(stdClass)#1 (1) { ["name"]=> string(9) "燕睿涛" }
另外還有個特別要說明的例子
<?php class T { private function show() { echo "我是T里面的私有函数:show\n"; } protected function who() { echo "我是T里面的保护函数:who\n"; } public function name() { echo "我是T里面的公共函数:name\n"; } } $func = Closure::bind(function ($obj) { $obj->show(); }, null); $test = new T(); $func($test);
上面的情況會輸出什麼呢,沒錯,會報錯,提示訪問不了私有屬性show
,這個時候,加上第三個參數就可以了,看了第三個參數不光影響$this
的作用域,
也可以影響參數的作用域。
Closure::bindTo
#bindTo
和bind
功能類似,這裡只是另外一種形式,都是複製目前閉包對象,綁定指定的$this對象和類別作用域。
,參數比bind
少了第一個,
後面兩個一樣,當然還有一個差異就是bindTo
不是靜態方法,是閉包才會存在的一個屬性方法。
範例
<?php class T { private function show() { echo "我是T里面的私有函数:show\n"; } protected function who() { echo "我是T里面的保护函数:who\n"; } public function name() { echo "我是T里面的公共函数:name\n"; } } $func = function () { $this->show(); $this->who(); $this->name(); }; $funcNew = $func->bindTo(new T(), T::class); $funcNew();
上面函數的輸出和bind
的類似
我是T里面的私有函数:show 我是T里面的保护函数:who 我是T里面的公共函数:name
一個trick
這個函數是在看composer產生的自動載入原始碼的時候碰到的,在composer中用的比較特別,下面是截取部分composer中的程式碼
// 文件autoload_real.php call_user_func(\Composer\Autoload\ComposerStaticInit898ad46cb49e20577400c63254121bac::getInitializer($loader)); // 文件autoload_static.php public static function getInitializer(ClassLoader $loader) { return \Closure::bind(function () use ($loader) { $loader->prefixLengthsPsr4 = ComposerStaticInit25885cdf386fdaafc0bce14bb5a7d06e::$prefixLengthsPsr4; $loader->prefixDirsPsr4 = ComposerStaticInit25885cdf386fdaafc0bce14bb5a7d06e::$prefixDirsPsr4; $loader->prefixesPsr0 = ComposerStaticInit25885cdf386fdaafc0bce14bb5a7d06e::$prefixesPsr0; $loader->classMap = ComposerStaticInit25885cdf386fdaafc0bce14bb5a7d06e::$classMap; }, null, ClassLoader::class); }
上面的程式碼比較奇特,在call_user_func
中,第一個感覺是傳錯參數了,其實不然,這裡呼叫了一個函數,這個函數會回傳一個Closure
對象,
也就是一個匿名函數,最後傳入的參數還是一個callable
型別。再看看這個回傳的閉包,裡面使用了use
,這是連接閉包和外部變數的橋樑。
至於這裡為什麼普通傳參數就可以,是因為php5裡面,對象形參和實參數指向相同的對象,函數裡面對對象的修改會反映到對像外面。
所以,上面這麼做是沒問題的,還有另外一種形式也可以
call_user_func(\Composer\Autoload\ComposerStaticInit898ad46cb49e20577400c63254121bac::getInitializer(), $loader); public static function getInitializer() { return \Closure::bind(function ($loader) { $loader->prefixLengthsPsr4 = ComposerStaticInit25885cdf386fdaafc0bce14bb5a7d06e::$prefixLengthsPsr4; $loader->prefixDirsPsr4 = ComposerStaticInit25885cdf386fdaafc0bce14bb5a7d06e::$prefixDirsPsr4; $loader->prefixesPsr0 = ComposerStaticInit25885cdf386fdaafc0bce14bb5a7d06e::$prefixesPsr0; $loader->classMap = ComposerStaticInit25885cdf386fdaafc0bce14bb5a7d06e::$classMap; }, null, ClassLoader::class); }
#總結
很久沒寫blog了,有時候太煩躁,靜不下心來,有時又有沒有找到想寫的東西。還是得靜下心來,好好做好每一件事,遇事情不要煩躁,心放大,心平氣和的處理每一件事。
相關教學推薦:《PHP教學》
以上是PHP使用Closure建立匿名函數的方法介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!

PHP和Python各有優勢,選擇應基於項目需求。 1.PHP適合web開發,語法簡單,執行效率高。 2.Python適用於數據科學和機器學習,語法簡潔,庫豐富。

PHP不是在消亡,而是在不斷適應和進化。 1)PHP從1994年起經歷多次版本迭代,適應新技術趨勢。 2)目前廣泛應用於電子商務、內容管理系統等領域。 3)PHP8引入JIT編譯器等功能,提升性能和現代化。 4)使用OPcache和遵循PSR-12標準可優化性能和代碼質量。

PHP的未來將通過適應新技術趨勢和引入創新特性來實現:1)適應云計算、容器化和微服務架構,支持Docker和Kubernetes;2)引入JIT編譯器和枚舉類型,提升性能和數據處理效率;3)持續優化性能和推廣最佳實踐。

在PHP中,trait適用於需要方法復用但不適合使用繼承的情況。 1)trait允許在類中復用方法,避免多重繼承複雜性。 2)使用trait時需注意方法衝突,可通過insteadof和as關鍵字解決。 3)應避免過度使用trait,保持其單一職責,以優化性能和提高代碼可維護性。

依賴注入容器(DIC)是一種管理和提供對象依賴關係的工具,用於PHP項目中。 DIC的主要好處包括:1.解耦,使組件獨立,代碼易維護和測試;2.靈活性,易替換或修改依賴關係;3.可測試性,方便注入mock對象進行單元測試。

SplFixedArray在PHP中是一種固定大小的數組,適用於需要高性能和低內存使用量的場景。 1)它在創建時需指定大小,避免動態調整帶來的開銷。 2)基於C語言數組,直接操作內存,訪問速度快。 3)適合大規模數據處理和內存敏感環境,但需謹慎使用,因其大小固定。

PHP通過$\_FILES變量處理文件上傳,確保安全性的方法包括:1.檢查上傳錯誤,2.驗證文件類型和大小,3.防止文件覆蓋,4.移動文件到永久存儲位置。

JavaScript中處理空值可以使用NullCoalescingOperator(??)和NullCoalescingAssignmentOperator(??=)。 1.??返回第一個非null或非undefined的操作數。 2.??=將變量賦值為右操作數的值,但前提是該變量為null或undefined。這些操作符簡化了代碼邏輯,提高了可讀性和性能。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

DVWA
Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

SAP NetWeaver Server Adapter for Eclipse
將Eclipse與SAP NetWeaver應用伺服器整合。

EditPlus 中文破解版
體積小,語法高亮,不支援程式碼提示功能

Dreamweaver Mac版
視覺化網頁開發工具

禪工作室 13.0.1
強大的PHP整合開發環境