超薄保护可调用

时间:2015-01-31 01:37:57

标签: php function closures slim php-closures

在Slim Framework中,有一个protect函数可以在函数中包含callables(即另一个可调用的函数)。 the manual中的说明是:

  

如果你想将一个闭包作为原始值存储而不是调用它怎么办?你可以这样做:

$app->myClosure = $app->container->protect(function () {});

查看源代码,我看到了:

/**
 * Protect closure from being directly invoked
 * @param  Closure $callable A closure to keep from being invoked and evaluated
 * @return Closure
 */
public function protect(\Closure $callable)
{
    return function () use ($callable) {
        return $callable;
    };
}

我想知道这是什么意思。在这里,我做了自己的测试:

$foo = function() {
    echo "Hello";
};

$bar = function () use ($foo) {
    return $foo;
};

var_dump($foo);
var_dump($bar);

这就是我得到的:

object(Closure)#1 (0) {
}
object(Closure)#2 (1) {
  ["static"]=>
  array(1) {
    ["foo"]=>
    object(Closure)#1 (0) {
    }
  }
}

我可以调用$bar()来返回可调用对象,但如果我可以使用$foo,为什么我会这样做呢?有人可以解释一下这个目的吗?

1 个答案:

答案 0 :(得分:2)

关于在运行时调用的闭包的全部内容。当你需要使用一个回调(将一个闭包作为可调用的\Closure传递给另一个函数)而不立即调用它时,它就变得明显了。

让我们来看看Slim运行中发生了什么。

因此,如果我们只是为资源分配一个闭包,就像这样

$app->foo = function () {
    return 'invoked foo returns this string';
};

或作为Slims单例资源

$app->container->singleton('foo', function () {
    return 'invoked foo returns this string';
});

它将分别在每次通话或第一次通话时调用......所以

$app->foo;

将返回字符串invoked foo returns this string

让我们说我们想要另一个函数来使用我们的callable(作为某种中间层),并希望用call_user_function()调用它。所以我们不想传入被调用的函数(它将传递返回的值),而是一个未被激活的闭包,我们通过使用protect()方法将闭包赋值给变量/资源来实现。

$app->bar = $app->container->protect(function () {
    return 'bar returns a callable closure';
});

为了进行演示,让我们将$app->foo$app->bar传递给call_user_function()

call_user_func($app->foo);

会抛出错误

"call_user_func() expects parameter 1 to be a valid callback,
 function 'invoked foo returns this string' not found or invalid function name"

因为它试图调用返回的字符串,其中

call_user_func($app->bar);

调用保存在$app->bar中的闭包并返回其返回字符串,如下所示:

"bar returns a callable closure"

我希望这个例子说明了Slim protect()方法的用处。