摘要:說(shuō)明本文主要學(xué)習(xí)的回調(diào)類(lèi)型通常在使用函數(shù)進(jìn)行回調(diào)時(shí),如使用進(jìn)行回調(diào)時(shí),需要傳入回調(diào),實(shí)際上有幾種的,在中也大量使用回調(diào),并根據(jù)場(chǎng)景不同傳入不同的回調(diào)類(lèi)型。開(kāi)發(fā)環(huán)境是把函數(shù)名作為類(lèi)型傳進(jìn)去作為回調(diào)類(lèi)型,形式如。
說(shuō)明:本文主要學(xué)習(xí)PHP的回調(diào)類(lèi)型callback type,通常在使用函數(shù)進(jìn)行回調(diào)時(shí),如使用call_user_func($callback, $parameters)進(jìn)行回調(diào)時(shí),需要傳入回調(diào)callback,實(shí)際上有幾種callback type的,在Laravel中也大量使用回調(diào),并根據(jù)場(chǎng)景不同傳入不同的回調(diào)類(lèi)型。
開(kāi)發(fā)環(huán)境:Laravel5.3 + PHP7
(Function/Static Class Method) Callback TypeFunction Callback Type是把函數(shù)名作為callable類(lèi)型傳進(jìn)去作為回調(diào)類(lèi)型,形式如:($function_name, $dependency)。Static Class Method Callable Type與其類(lèi)似,是把類(lèi)名+靜態(tài)方法名傳進(jìn)去作為回調(diào)類(lèi)型,形式如:("$class_name::$static_method_name", $dependency)??聪翽HPUnit測(cè)試,看看如何使用callback type,爆綠燈:
assertSame($expected, $actual); } public function testStaticClassMethodCallback() { // Arrange $expected = "container"; // Actual $actual = call_user_func("MyRightCapitalContainerTestsStaticClassMethodCallback::staticClassMethod", "container"); // ("$class_name::$static_method_name", $dependency) // Assert $this->assertSame($expected, $actual); } } function functionCallback($app) { return $app; } class StaticClassMethodCallback { public static function staticClassMethod($app) { return $app; } }(Class Method/Relation Class Method) Callback Type
Class Method Callback Type也是類(lèi)名+靜態(tài)方法名,只不過(guò)形式稍不一樣,形式如:([$class_name, $method_name], $dependency)。Relation Class Method Callback Type是可以使用父類(lèi)的方法傳進(jìn)去作為回調(diào),形式如:([$class_name, "parent::$method_name"], $dependency)。寫(xiě)個(gè)PHPUnit測(cè)試看下使用:
public function testClassMethodCallback() { // Arrange $expected = "container"; // Actual $actual = call_user_func([ClassMethodCallback::class, "classMethod"], "container"); // ([$class_name, $method_name], $dependency) // Assert $this->assertSame($expected, $actual); } public function testRelationClassMethodCallback() { // Arrange $expected = "container/container"; // Actual $actual = call_user_func([ClassMethodCallback::class, "parent::classMethod"], "container"); // ([$class_name, "parent::$method_name"], $dependency) // Assert $this->assertSame($expected, $actual); } class ClassMethodCallback extends ParentClassMethodCallback { public static function classMethod($app) { return $app; } } class ParentClassMethodCallback { public static function classMethod($app) { return $app . "/" . $app; } }Object Method Callback Type
Object Method Callback Type是把對(duì)象方法作為參數(shù)傳進(jìn)去作為回調(diào),形式如:([$object, $method_name], $dependency),寫(xiě)個(gè)PHPUnit測(cè)試:
public function testObjectMethodCallback() { // Arrange $class_method_callback = new ClassMethodCallback(); $expected = "container"; // Actual $actual = call_user_func([$class_method_callback, "objectMethod"], "container"); // ([$object, $method_name], $dependency) // Assert $this->assertSame($expected, $actual); } class ClassMethodCallback extends ParentClassMethodCallback { public static function classMethod($app) { return $app; } public function objectMethod($app) { return $app; } }Closure
把Closure作為參數(shù)傳進(jìn)去作為回調(diào)參數(shù)這種方式在Laravel中大量使用,比如Laravel的Pipeline源碼就大量使用這種方式,Pipeline的源碼可看:Laravel學(xué)習(xí)筆記之Middleware源碼解析。寫(xiě)下PHPUnit測(cè)試看下:
public function testClosureCallback() { // Arrange // Actual $actual = call_user_func(getClosure(), "stack", "pipe"); $actual_value = call_user_func($actual, "request"); // Assert $this->assertInstanceOf(Closure::class, $actual); $this->assertSame("request/stack/pipe", $actual_value); } function getClosure() { return function ($stack, $pipe) { return function ($passable) use ($stack, $pipe) { return $passable . "/" . $stack . "/" . $pipe; }; }; }
最后,給出整個(gè)源碼和測(cè)試結(jié)果:
assertSame($expected, $actual); } public function testStaticClassMethodCallback() { // Arrange $expected = "container"; // Actual $actual = call_user_func("MyRightCapitalContainerTestsStaticClassMethodCallback::staticClassMethod", "container"); // ("$class_name::$static_method_name", $dependency) // Assert $this->assertSame($expected, $actual); } public function testClassMethodCallback() { // Arrange $expected = "container"; // Actual $actual = call_user_func([ClassMethodCallback::class, "classMethod"], "container"); // ([$class_name, $method_name], $dependency) // Assert $this->assertSame($expected, $actual); } public function testRelationClassMethodCallback() { // Arrange $expected = "container/container"; // Actual $actual = call_user_func([ClassMethodCallback::class, "parent::classMethod"], "container"); // ([$class_name, "parent::$method_name"], $dependency) // Assert $this->assertSame($expected, $actual); } public function testObjectMethodCallback() { // Arrange $class_method_callback = new ClassMethodCallback(); $expected = "container"; // Actual $actual = call_user_func([$class_method_callback, "objectMethod"], "container"); // ([$object, $method_name], $dependency) // Assert $this->assertSame($expected, $actual); } public function testClosureCallback() { // Arrange // Actual $actual = call_user_func(getClosure(), "stack", "pipe"); $actual_value = call_user_func($actual, "request"); // Assert $this->assertInstanceOf(Closure::class, $actual); $this->assertSame("request/stack/pipe", $actual_value); } } function getClosure() { return function ($stack, $pipe) { return function ($passable) use ($stack, $pipe) { return $passable . "/" . $stack . "/" . $pipe; }; }; } function functionCallback($app) { return $app; } class StaticClassMethodCallback { public static function staticClassMethod($app) { return $app; } } class ClassMethodCallback extends ParentClassMethodCallback { public static function classMethod($app) { return $app; } public function objectMethod($app) { return $app; } } class ParentClassMethodCallback { public static function classMethod($app) { return $app . "/" . $app; } }
總結(jié):本文主要總結(jié)下PHP的Callback Type,便于提高自己的代碼設(shè)計(jì)能力。遇到好的技術(shù)再聊,到時(shí)見(jiàn)。
歡迎關(guān)注Laravel-China。
RightCapital招聘Laravel DevOps
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/30472.html
摘要:看下兩個(gè)方法的源碼同樣是使用了對(duì)象來(lái)添加命令和。 說(shuō)明:本文主要學(xué)習(xí)Schema Builder和Migration System的使用及相關(guān)原理。傳統(tǒng)上在設(shè)計(jì)database時(shí)需要寫(xiě)大量的SQL語(yǔ)句,但Laravel提供了Schema Builder這個(gè)神器使得在設(shè)計(jì)database時(shí)使用面向?qū)ο蠓椒▉?lái)做,不需要寫(xiě)一行SQL,并且還提供了另一個(gè)神器Migration System,可...
摘要:,看下源碼返回很容易知道返回值是,然后將該值存儲(chǔ)在變量中,這時(shí)??聪碌脑创a去除掉字符后為返回從源碼中可知道返回值為,這時(shí)。 說(shuō)明:本文主要學(xué)習(xí)下Query Builder編譯Fluent Api為SQL的細(xì)節(jié)和執(zhí)行SQL的過(guò)程。實(shí)際上,上一篇聊到了IlluminateDatabaseQueryBuilder這個(gè)非常重要的類(lèi),這個(gè)類(lèi)含有三個(gè)主要的武器:MySqlConnection, M...
摘要:說(shuō)明本文主要學(xué)習(xí)容器的實(shí)例化過(guò)程,主要包括等四個(gè)過(guò)程??聪碌脑创a如果是數(shù)組,抽取別名并且注冊(cè)到中,上文已經(jīng)討論實(shí)際上就是的。 說(shuō)明:本文主要學(xué)習(xí)Laravel容器的實(shí)例化過(guò)程,主要包括Register Base Bindings, Register Base Service Providers , Register Core Container Aliases and Set the ...
摘要:提供了一些函數(shù)處理操作的內(nèi)置函數(shù),主要有開(kāi)發(fā)環(huán)境是調(diào)用回調(diào)函數(shù),并把一個(gè)數(shù)組作為參數(shù)傳進(jìn)去作為回調(diào)函數(shù)的參數(shù)也是調(diào)用回調(diào)函數(shù),區(qū)別是并沒(méi)有要求把數(shù)組作為參數(shù)傳進(jìn)回調(diào)函數(shù)做參數(shù)。 說(shuō)明:Laravel中經(jīng)常使用PHP的Function Handling來(lái)設(shè)計(jì)代碼,本文主要學(xué)習(xí)PHP的Function Handling特性,來(lái)提高寫(xiě)代碼時(shí)的設(shè)計(jì)質(zhì)量。PHP提供了一些函數(shù)處理操作的內(nèi)置函數(shù),...
摘要:說(shuō)明本文主要學(xué)習(xí)的模塊的源碼邏輯,把自己的一點(diǎn)點(diǎn)研究心得分享出來(lái),希望對(duì)別人有所幫助。實(shí)際上,使用了的重載學(xué)習(xí)筆記之重載,通過(guò)魔術(shù)方法調(diào)用里的,而這個(gè)實(shí)際上就是,該中有方法,可以調(diào)用。 說(shuō)明:本文主要學(xué)習(xí)Laravel的Filesystem模塊的源碼邏輯,把自己的一點(diǎn)點(diǎn)研究心得分享出來(lái),希望對(duì)別人有所幫助??偟膩?lái)說(shuō),F(xiàn)ilesystem模塊的源碼也比較簡(jiǎn)單,Laravel的Illumi...
閱讀 931·2021-11-22 13:54
閱讀 2862·2021-09-28 09:36
閱讀 2996·2019-08-30 15:55
閱讀 1966·2019-08-30 15:44
閱讀 559·2019-08-29 12:31
閱讀 2577·2019-08-28 18:18
閱讀 1212·2019-08-26 13:58
閱讀 1399·2019-08-26 13:44