摘要:復(fù)制一個(gè)閉包,綁定指定的對(duì)象和類作用域。匿名函數(shù)目前是通過類來實(shí)現(xiàn)的。
通過幾個(gè)栗子認(rèn)識(shí)PHP閉包
一、栗子1 用作于回調(diào)
二、栗子2 用作于變量賦值
三、栗子3 從父作用域繼承變量
四、栗子4的前提條件,簡(jiǎn)單理解call_user_func_array()和call_user_func()方法
1. call_user_func — 把第一個(gè)參數(shù)作為回調(diào)函數(shù)調(diào)用
2. call_user_func_array — 調(diào)用回調(diào)函數(shù),并把一個(gè)數(shù)組參數(shù)作為回調(diào)函數(shù)的參數(shù)
五、栗子4 綁定閉包在指定對(duì)象
1. Closure::bindTo — 復(fù)制當(dāng)前閉包對(duì)象,綁定指定的$this對(duì)象和類作用域。
2. Closure::bind — 復(fù)制一個(gè)閉包,綁定指定的$this對(duì)象和類作用域。
六、參考資料
有收獲的話請(qǐng)加顆小星星,沒有收獲的話可以 反對(duì) 沒有幫助 舉報(bào)三連
示例代碼
本文地址
本人能力有限,如遇到什么不對(duì)的地方還望指出修正,謝謝
所有栗子的輸出都使用symfony/var-dumpe美化了
匿名函數(shù)(Anonymous functions),也叫閉包函數(shù)(closures),允許 臨時(shí)創(chuàng)建一個(gè)沒有指定名稱的函數(shù)。最經(jīng)常用作回調(diào)函數(shù)(callback)參數(shù)的值。當(dāng)然,也有其它應(yīng)用的情況。
匿名函數(shù)目前是通過 Closure 類來實(shí)現(xiàn)的。
一、栗子1 用作于回調(diào)$rs = preg_replace_callback("/-([a-z])/", function ($match) { return strtoupper($match[1]); }, "hello-world"); dump($rs); // "helloWorld"二、栗子2 用作于變量賦值
$greet = function ($name) { dump($name); }; dump($greet instanceof Closure); // true $greet("PHP"); // "PHP"三、栗子3 從父作用域繼承變量
$message = "hello"; $example = function () use ($message) { dump($message); }; dump($example instanceof Closure); // true $example(); // "hello"四、栗子4的前提條件,簡(jiǎn)單理解call_user_func_array()和call_user_func()方法 1. call_user_func — 把第一個(gè)參數(shù)作為回調(diào)函數(shù)調(diào)用
function call_user_func ($function, ...$parameter) {}
該方法接收多個(gè)參數(shù),第一個(gè)就是回調(diào)函數(shù),可以是普通函數(shù),也可以是閉包函數(shù),后面的多個(gè)參數(shù)都是作為函數(shù)回調(diào)使用
$rs = call_user_func(function (...$params) { return func_get_args(); }, 1, 2, 3); dump($rs); // [1,2,3]2. call_user_func_array — 調(diào)用回調(diào)函數(shù),并把一個(gè)數(shù)組參數(shù)作為回調(diào)函數(shù)的參數(shù)
function call_user_func_array ($function, array $param_arr) {}
該方法接收2個(gè)參數(shù),第一個(gè)就是回調(diào)函數(shù),可以是普通函數(shù),也可以是閉包函數(shù),后面的數(shù)組參數(shù)都是作為函數(shù)回調(diào)使用
$rs = call_user_func_array(function (array $params) { return func_get_args(); }, [1, 2, 3]); dump($rs); // [1,2,3]五、栗子4 綁定閉包在指定對(duì)象
樓主見解是將方法綁定到指定類上,使得方法也可以使用類的屬性和方法,非常適合配合__call()魔術(shù)方法和call_user_func_array方法一起使用
1. Closure::bindTo — 復(fù)制當(dāng)前閉包對(duì)象,綁定指定的$this對(duì)象和類作用域。function bindTo($newthis, $newscope = "static") { }
1 && $arguments[0] instanceof Closure) { return call_user_func_array($arguments[0]->bindTo($this), array_slice($arguments, 1)); } throw new InvalidArgumentException("沒有這個(gè)方法"); } } // 測(cè)試 public function testClosureBindTo() { $obj = new ClosureBindTo(); $this->assertEquals(2, $obj->add(function (array $params) { return ++$params[0]; }, [1])); // 測(cè)試同一個(gè)實(shí)例 $newObj = $obj->test(function (array $params){ return $this; }, [1]); $this->assertTrue($newObj instanceof $obj); }2. Closure::bind — 復(fù)制一個(gè)閉包,綁定指定的$this對(duì)象和類作用域。
static function bind(Closure $closure, $newthis, $newscope = "static") { }
bind函數(shù)是bindTo的靜態(tài)表示
methods[$name] = Closure::bind($callback, $this, get_class()); } public function __call(string $name, array $arguments) { if (isset($this->methods[$name])) { return call_user_func_array($this->methods[$name], $arguments); } throw new RuntimeException("不存在方法[{$name}]"); } } // 測(cè)試 public function testClosureBind() { $obj = new ClosureBind(); $obj->addMethod("add", function (array $params) { return ++$params[0]; }); $this->assertEquals(2, $obj->add([1])); // 測(cè)試同一個(gè)實(shí)例 $obj->addMethod("test", function (array $params) { return $this; }); $this->assertTrue($obj->test([1]) instanceof $obj); }六、參考資料
php手冊(cè)
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/29847.html
摘要:但是,必須強(qiáng)調(diào),閉包是一個(gè)運(yùn)行期概念。通過原型鏈可以實(shí)現(xiàn)繼承,而與閉包相關(guān)的就是作用域鏈。常理來說,一個(gè)函數(shù)執(zhí)行完畢,其執(zhí)行環(huán)境的作用域鏈會(huì)被銷毀。所以此時(shí),的作用域鏈雖然銷毀了,但是其活動(dòng)對(duì)象仍在內(nèi)存中。 學(xué)習(xí)Javascript閉包(Closure)javascript的閉包JavaScript 閉包深入理解(closure)理解 Javascript 的閉包JavaScript ...
摘要:前言這段時(shí)間一直在消化作用域鏈和閉包的相關(guān)知識(shí)。而作用域鏈則是這套規(guī)則這套規(guī)則的具體運(yùn)行。是變量對(duì)象的縮寫那這樣放有什么好處呢我們知道作用域鏈保證了當(dāng)前執(zhí)行環(huán)境對(duì)符合訪問權(quán)限的變量和函數(shù)的有序訪問。 前言:這段時(shí)間一直在消化作用域鏈和閉包的相關(guān)知識(shí)。之前看《JS高程》和一些技術(shù)博客,對(duì)于這些概念的論述多多少少不太清楚或者不太完整,包括一些大神的技術(shù)文章。這也給我的學(xué)習(xí)上造成了一些困惑,...
摘要:圖片中的作用域鏈,是全局執(zhí)行環(huán)境中的作用域鏈。然后此活動(dòng)對(duì)象被推入作用域鏈的最前端。在最后調(diào)用的時(shí)候,創(chuàng)建先構(gòu)建作用域鏈,再創(chuàng)建執(zhí)行環(huán)境,再創(chuàng)建執(zhí)行環(huán)境的時(shí)候發(fā)現(xiàn)了一個(gè)變量標(biāo)識(shí)符。 從圖書館翻過各種JS的書之后,對(duì)作用域/執(zhí)行環(huán)境/閉包這些概念有了一個(gè)比較清晰的認(rèn)識(shí)。 栗子說明一切 第一個(gè)栗子 來看一個(gè)來自ECMA-262的栗子: var x = 10; (function foo(...
摘要:所以,有另一種說法認(rèn)為閉包是由函數(shù)和與其相關(guān)的引用環(huán)境組合而成的實(shí)體。所以本文中將以維基百科中的定義為準(zhǔn)即在計(jì)算機(jī)科學(xué)中,閉包,又稱詞法閉包或函數(shù)閉包,是引用了自由變量的函數(shù)。 閉包(closure)是JavaScript中一個(gè)神秘的概念,許多人都對(duì)它難以理解,我也一直處于似懂非懂的狀態(tài),前幾天深入了解了一下執(zhí)行環(huán)境以及作用域鏈,可戳查看詳情,而閉包與作用域及作用域鏈的關(guān)系密不可分,所...
摘要:框架中就是使用服務(wù)容器來實(shí)現(xiàn)控制反轉(zhuǎn)和依賴注入。容器依賴注入的實(shí)現(xiàn)實(shí)現(xiàn)原理需要了解的知識(shí)點(diǎn)閉包匿名函數(shù)匿名函數(shù),也叫閉包函數(shù),允許臨時(shí)創(chuàng)建一個(gè)沒有指定名稱的函數(shù)反射以上版本具有完整的反射,添加了對(duì)類接口函數(shù)方法和擴(kuò)展進(jìn)行反向工程的能力。 前言 通過實(shí)現(xiàn)laravel 框架功能,以便深入理解laravel框架的先進(jìn)思想。 什么是服務(wù)容器 服務(wù)容器是用來管理類依賴與運(yùn)行依賴注入的工具。La...
閱讀 2838·2021-11-19 09:40
閱讀 5700·2021-09-27 14:10
閱讀 2170·2021-09-04 16:45
閱讀 1580·2021-07-25 21:37
閱讀 3059·2019-08-30 10:57
閱讀 3060·2019-08-28 17:59
閱讀 1116·2019-08-26 13:46
閱讀 1478·2019-08-26 13:27