匿名函数内的返回函数。为什么?

时间:2015-05-28 03:40:42

标签: php

考虑来自Slim PHP的this example,它用作中间件

这是什么区别

$authenticateForRole = function ( $role = 'member' ) {
    return function () use ( $role ) {
        $user = User::fetchFromDatabaseSomehow();
        if ( $user->belongsToRole($role) === false ) {
            $app = \Slim\Slim::getInstance();
            $app->flash('error', 'Login required');
            $app->redirect('/login');
        }
    };
};    

这个,

$authenticateForRole = function ( $role = 'member' ) {
    $user = User::fetchFromDatabaseSomehow();
    if ( $user->belongsToRole($role) === false ) {
        $app = \Slim\Slim::getInstance();
        $app->flash('error', 'Login required');
        $app->redirect('/login');
    }
};

Aren那些功能是否相同?

1 个答案:

答案 0 :(得分:1)

在slim框架和中间件的上下文中,以及与此问题相关的特定示例。

逻辑被封装在一个闭包中,因此可以在稍后由框架中间件逻辑调用它并保留$ role的用户参数。

用于参考和上下文 - 来自原始帖子的使用代码

$app->get('/foo', $authenticateForRole('admin'), function () {
//Display admin control panel
});

理解调用上下文,你应该明白为什么这两者是不同的。

从这一点开始,在提到您提供的第二个代码时,我将在代码中将其引用为$ authenticateForRole2。

案例1 - 失败

使用如下所示的第二个代码:将导致立即执行函数$ authenticateForRole2,返回值(null)将作为middlewere参数传递。 "中间"参数应该是一个可调用/可调用的对象,这就是为什么这段代码不正确。

$app->get('/foo', $authenticateForRole2('admin'), function () {
//Display admin control panel
});

案例2 - lambada无法控制$ role(~Works)

部分工作,而不是100%相同的功能 它将使用函数声明中设置的默认$ role。在定义api(设置路径)时,您无法提供不同的$ role参数

$app->get('/foo', $authenticateForRole2, function () {
//Display admin control panel
});
<3>案例3 - 重复声明(工作但不推荐)

这应该有效,但需要重复每个$ role值的声明。例如,如果一条路径用于“管理员”。另一个是&#39;成员&#39;

注意我在函数中移动了$ role,因为在调用它时,slim会将一个对象作为参数传递给middlewere函数。

$app->get('/foo', 
    function()  {  
        $role = 'admin'
        $user = User::fetchFromDatabaseSomehow();
        if ( $user->belongsToRole($role) === false ) {
            $app = \Slim\Slim::getInstance();
            $app->flash('error', 'Login required');
            $app->redirect('/login');
        }
} , function () {
//Display admin control panel
});

$app->get('/bar', 
    function (){  
        $role = 'member'
        $user = User::fetchFromDatabaseSomehow();
        if ( $user->belongsToRole($role) === false ) {
            $app = \Slim\Slim::getInstance();
            $app->flash('error', 'Login required');
            $app->redirect('/login');
        }
} , function () {
//Display admin control panel
});

案例4(原始示例)

原始示例使用闭包包技巧为角色身份验证方法提供DRY方式。

$app->get('/foo', $authenticateForRole('admin'), function () {
//Display admin control panel
});  

$app->get('/bar', $authenticateForRole('member'), function () {
//Display member control panel
});