文档章节

Laravel5.3之Callback Type

botkenni
 botkenni
发布于 2016/11/15 13:59
字数 812
阅读 11
收藏 0

说明:本文主要学习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,便于提高自己的代码设计能力。遇到好的技术再聊,到时见。

© 著作权归作者所有

共有 人打赏支持
botkenni
粉丝 20
博文 409
码字总数 434882
作品 0
西城
程序员
私信 提问
晚黎/iDashboard

iDashboard - Laravel5.3基本的权限管理系统 当前分支为Laravel版本~,Vue2.0版本戳这里 ,Vue2.0只完成了部分,用户管理,权限管理以及角色管理,其他的都还没有做。本人时间有限,重复的增删...

晚黎
2016/11/07
0
0
Laravel5.3之Session源码解析(下)

说明:在中篇中学习了session的CRUD增删改查操作,本篇主要学习关闭session的相关源码。实际上,在Laravel5.3中关闭session主要包括两个过程:保存当前URL到session介质中;在Response Head...

botkenni
2016/11/19
56
0
jQuery)扩展jQuery系列之一 模拟alert,confirm

全部代码 复制代码 代码如下: /** * @author xing */ (function($){ $.extend({ alert:function(html,callback){ var dialog=new Dialog(); dialog.build('alert',callback,html); }, confir......

wolf_su
2013/07/03
0
0
php的sso单点登录实现方法

本文实例讲述了php的sso单点登录实现方法。分享给大家供大家参考。具体分析如下: 这里详细讲到了几点: 1、点击登录跳转到SSO登录页面并带上当前应用的callback地址 2、登录成功后生成COOKI...

bengozhong
2016/08/15
8
0
php的sso单点登录实现方法

本文实例讲述了php的sso单点登录实现方法。分享给大家供大家参考。具体分析如下: 这里详细讲到了几点: 1、点击登录跳转到SSO登录页面并带上当前应用的callback地址 2、登录成功后生成COOKI...

james_laughing
2016/04/19
41
0

没有更多内容

加载失败,请刷新页面

加载更多

深入 理解char * ,char ** ,char a[ ] ,char *a[] 的区别

C语言中由于指针的灵活性,导致指针能代替数组使用,或者混合使用,这些导致了许多指针和数组的迷惑,因此,刻意再次深入探究了指针和数组这玩意儿,其他类型的数组比较简单,容易混淆的是字...

天王盖地虎626
31分钟前
3
0
关于我这三年的架构历程(待完成)

从16年7月实习至今,快三年的开发经历中,经手了好几个项目。目前有幸作为一个项目的负责人,完成了一个项目的完全架构设计。因此想记录下这份架构设计中的点点面面。 总架构: 基于DNS的负载...

赵熠熠
32分钟前
1
0
springboot 使用 flyway 进行数据库版本管理

要在启动时自动运行Flyway数据库迁移,请将其添加 org.flywaydb:flyway-core到类路径中。 迁移是表单中的脚本V<VERSION>__<NAME>.sql(使用<VERSION>下划线分隔的版本,例如“1”或“2_1”)...

NotFound403
51分钟前
5
0
spring 5.1.5版本(二)

spring 5.1.5版本(一) spring 5.1.5版本(二) spring 5.1.5版本(三) 对象创建方式 方式一 applicationContext.xml <?xml version='1.0' encoding='UTF-8'?><beans xmlns="http://ww......

gwl_
53分钟前
1
0
CMake生成Mingw用的Make文件

CMake 在win下 默认会生成vc++的nmake用的make 当没安装时 就会报 -- Building for: NMake Makefiles -- The C compiler identification is unknown -- The CXX compiler identification is......

shzwork
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部