确定一个变量是不是是 PHP 中的有效闭包

Posted

技术标签:

【中文标题】确定一个变量是不是是 PHP 中的有效闭包【英文标题】:Determining, if a variable is a valid closure in PHP确定一个变量是否是 PHP 中的有效闭包 【发布时间】:2011-10-29 09:51:40 【问题描述】:

使用以下函数:

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

除了匿名闭包函数之外,这还能返回 true 吗?如果是这样,确定变量是否为闭包的正确方法是什么?

非常感谢

【问题讨论】:

对象如果实现了__invoke,也可以调用。 【参考方案1】:

检查回调是否为实际闭包的最确定方法是:

function is_closure($t) 
    return $t instanceof \Closure;

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

【讨论】:

一些让我一两分钟都被绊倒的事情......如果你的代码是命名空间的,请确保转义 \Closure 以返回全局命名空间。 你不需要做is_object($t),为非对象做instanceof总是返回false。 在 php 7.4 上这不起作用。 print_r 显示 Object Closure 但 instanceof Closure 返回 false @MarkusRenéEinicher 我猜你的用法是在命名空间内。 (已编辑。) @mario 哈!当然!完全忘记了这一点。 instanceof \Closure 是!【参考方案2】:

我认为您可以使用instanceof Closure,尽管manual 声明不应该依赖它。我想它现在可以工作

匿名函数目前是使用闭包类实现的。这是一个实现细节,不应依赖。

更新 闭包manual page 已经更新了这方面的指导。看来现在可以依赖这种行为了。

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

【讨论】:

@mario 打败了我,但我将把它留在这里以获取更多信息(除非 mario 想将它与他的答案合并)【参考方案3】:

php.net 建议使用反射来确定变量是否包含有效的闭包

我用这个小帮手

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

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

【讨论】:

【参考方案4】:

反射 http://www.php.net/manual/en/reflectionfunctionabstract.isclosure.php 支持此功能

【讨论】:

【参考方案5】:

如果您收到关于不存在 ReflectionFunction 的错误,请在上课前使用 反斜杠

// Closure
$closure = function () ; 
$reflection = new \ReflectionFunction($closure);
// checkout if it is a closure
$test->isTrue($reflection->isClosure());

【讨论】:

以上是关于确定一个变量是不是是 PHP 中的有效闭包的主要内容,如果未能解决你的问题,请参考以下文章

PHP和Go中的闭包变量作用域

PHP 闭包获取外部变量和global关键字声明变量的区别

PHP中的闭包和匿名函数

浅析PHP中的闭包和匿名函数

Python中的闭包

js 闭包 具体作用?