Laravel5.3之Callback Type

℡╲_俬逩灬. 提交于 2019-11-29 06:49:23

说明:本文主要学习PHP的回调类型callback type,通常在使用函数进行回调时,如使用call_user_func($callback, $parameters)进行回调时,需要传入回调callback,实际上有几种callback type的,在Laravel中也大量使用回调,并根据场景不同传入不同的回调类型。

开发环境:Laravel5.3 + PHP7

(Function/Static Class Method) Callback Type

Function Callback Type是把函数名作为callable类型传进去作为回调类型,形式如:($function_name, $dependency)。Static Class Method Callable Type与其类似,是把类名+静态方法名传进去作为回调类型,形式如:("$class_name::$static_method_name", $dependency)。看下PHPUnit测试,看看如何使用callback type,爆绿灯:

<?php  namespace MyRightCapital\Container\Tests;  class Callback extends \PHPUnit_Framework_TestCase {     public function testFunctionCallback()     {         // Arrange         $expected = 'container';                  // Actual         $actual = call_user_func('MyRightCapital\Container\Tests\functionCallback', 'container'); // ($function_name, $dependency)                  // Assert         $this->assertSame($expected, $actual);     }          public function testStaticClassMethodCallback()     {         // Arrange         $expected = 'container';                  // Actual         $actual = call_user_func('MyRightCapital\Container\Tests\StaticClassMethodCallback::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也是类名+静态方法名,只不过形式稍不一样,形式如:([$class_name, $method_name], $dependency)。Relation Class Method Callback Type是可以使用父类的方法传进去作为回调,形式如:([$class_name, "parent::$method_name"], $dependency)。写个PHPUnit测试看下使用:

    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是把对象方法作为参数传进去作为回调,形式如:([$object, $method_name], $dependency),写个PHPUnit测试:

    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作为参数传进去作为回调参数这种方式在Laravel中大量使用,比如Laravel的Pipeline源码就大量使用这种方式,Pipeline的源码可看:Laravel5.3Middleware源码解析。写下PHPUnit测试看下:

    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;             };         };     }     

最后,给出整个源码和测试结果:

<?php  namespace MyRightCapital\Container\Tests;  class Callback extends \PHPUnit_Framework_TestCase {     public function testFunctionCallback()     {         // Arrange         $expected = 'container';                  // Actual         $actual = call_user_func('MyRightCapital\Container\Tests\functionCallback', 'container'); // ($function_name, $dependency)                  // Assert         $this->assertSame($expected, $actual);     }          public function testStaticClassMethodCallback()     {         // Arrange         $expected = 'container';                  // Actual         $actual = call_user_func('MyRightCapital\Container\Tests\StaticClassMethodCallback::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;     } }

总结:本文主要总结下PHP的Callback Type,便于提高自己的代码设计能力。遇到好的技术再聊,到时见。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!