资讯专栏INFORMATION COLUMN

Laravel学习笔记之Callback Type

ChanceWong / 1413人阅读

摘要:说明本文主要学习的回调类型通常在使用函数进行回调时,如使用进行回调时,需要传入回调,实际上有几种的,在中也大量使用回调,并根据场景不同传入不同的回调类型。开发环境是把函数名作为类型传进去作为回调类型,形式如。

说明:本文主要学习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,爆绿灯:

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也是类名+静态方法名,只不过形式稍不一样,形式如:([$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的源码可看:Laravel学习笔记之Middleware源码解析。写下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;
            };
        };
    }
    

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

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

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

欢迎关注Laravel-China。

RightCapital招聘Laravel DevOps

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/30472.html

相关文章

  • Laravel学习笔记Schema Builder 和 Migration System(上)

    摘要:看下两个方法的源码同样是使用了对象来添加命令和。 说明:本文主要学习Schema Builder和Migration System的使用及相关原理。传统上在设计database时需要写大量的SQL语句,但Laravel提供了Schema Builder这个神器使得在设计database时使用面向对象方法来做,不需要写一行SQL,并且还提供了另一个神器Migration System,可...

    nevermind 评论0 收藏0
  • Laravel 学习笔记 Query Builder 源码解析(下)

    摘要:,看下源码返回很容易知道返回值是,然后将该值存储在变量中,这时。看下的源码去除掉字符后为返回从源码中可知道返回值为,这时。 说明:本文主要学习下Query Builder编译Fluent Api为SQL的细节和执行SQL的过程。实际上,上一篇聊到了IlluminateDatabaseQueryBuilder这个非常重要的类,这个类含有三个主要的武器:MySqlConnection, M...

    qpal 评论0 收藏0
  • Laravel学习笔记IoC Container实例化源码解析

    摘要:说明本文主要学习容器的实例化过程,主要包括等四个过程。看下的源码如果是数组,抽取别名并且注册到中,上文已经讨论实际上就是的。 说明:本文主要学习Laravel容器的实例化过程,主要包括Register Base Bindings, Register Base Service Providers , Register Core Container Aliases and Set the ...

    ningwang 评论0 收藏0
  • Laravel学习笔记函数处理(Function Handling)

    摘要:提供了一些函数处理操作的内置函数,主要有开发环境是调用回调函数,并把一个数组作为参数传进去作为回调函数的参数也是调用回调函数,区别是并没有要求把数组作为参数传进回调函数做参数。 说明:Laravel中经常使用PHP的Function Handling来设计代码,本文主要学习PHP的Function Handling特性,来提高写代码时的设计质量。PHP提供了一些函数处理操作的内置函数,...

    Rindia 评论0 收藏0
  • Laravel学习笔记Filesystem源码解析(上)

    摘要:说明本文主要学习的模块的源码逻辑,把自己的一点点研究心得分享出来,希望对别人有所帮助。实际上,使用了的重载学习笔记之重载,通过魔术方法调用里的,而这个实际上就是,该中有方法,可以调用。 说明:本文主要学习Laravel的Filesystem模块的源码逻辑,把自己的一点点研究心得分享出来,希望对别人有所帮助。总的来说,Filesystem模块的源码也比较简单,Laravel的Illumi...

    AlphaGooo 评论0 收藏0

发表评论

0条评论

ChanceWong

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<