2011-08-18 51 views
20

一个有效的封闭使用以下功能:确定,如果一个变量是在PHP

function is_closure($t) { return (!is_string($t) && is_callable($t)); }

可这回真为别的,就不是一个匿名闭包功能?如果是这样,如果一个变量是闭包,那么确定的正确方法是什么?

非常感谢

+2

如果实现['__invoke'](http://www.php.net/manual/en/language.oop5.magic.php#language.oop5.magic.invoke),对象也可以调用。 – mario

回答

40

最确定的方式来检查,如果回调是一个实际的闭包:

function is_closure($t) { 
    return is_object($t) && ($t instanceof Closure); 
} 

所有的匿名函数中表示为PHP类型Closure的对象。 (回到上面的评论,碰巧实现了__invoke()方法。)

+4

让我绊倒了一两分钟的东西......如果你的代码是命名空间的,确保转义\ Closure返回到全局命名空间。 – Jim

+7

您不需要执行'is_object($ t)',为非对象执行'instanceof'将始终返回false。 –

13

我认为你可以使用instanceof Closure,尽管manual声明不应该依赖这个。我想它现在可以运行

匿名函数当前使用Closure类实现。这是一个实现细节,不应该依赖。

更新 的封闭manual page已更新了该公司的指导。看来现在可以依靠这种行为。

在PHP 5.3中实现的匿名函数产生这种类型的对象。这个事实过去被认为是一个实现细节,但现在可以依赖它了。

+0

@mario打败了我,但我会在这里留下这些额外的信息(除非马里奥想把它与他的答案合并) – Phil

2

php.net建议使用反射弄清楚如果变量中包含一个有效的封闭与否

我用这个小帮手

function isClosure($suspected_closure) { 
    $reflection = new ReflectionFunction($suspected_closure); 

    return (bool) $reflection->isClosure(); 
} 
0

如果您收到有关该错误的错误ReflectionFunction,请在课前使用反斜杠

// Closure 
$closure = function() {}; 
$reflection = new \ReflectionFunction($closure); 
// checkout if it is a closure 
$test->isTrue($reflection->isClosure()); 
相关问题