我的目标是在if()语句中放入一些复杂的逻辑。假设我有一个值数组如果数组中的所有值都是非零的,我要执行一段代码。通常,我可以说,$valid = true
, foreach
是我的数组,当找到零时设置$valid = false
。然后我运行我的代码if ($valid)
。或者,我可以将循环放入函数中,并将该函数放入if()
的顶部。
但是我很懒,所以我不想在一堆"有效"标志上浪费时间,我也不想写一个只在一个地方使用的全新函数。
假设我有这个:
if ($q = function() { return 'foo'; }) {
echo $q;
}
else {
echo 'false';
}
我期待if
得到'foo'
,其计算结果为true。我的闭包被提交给$q
并执行语句。$q
返回字符串foo
,并打印'foo'。
相反,我得到错误Object of class Closure could not be converted to string
。
那么我们试试这个:
if (function() { return false; }) {
echo 'foo';
}
else {
echo 'true';
}
我期望我的函数会返回false并且打印'true'。相反,输出'foo'。
我做这件事的方式有什么问题吗?它似乎在说,"是的,这肯定是一个函数!"而不是"不,因为函数的求值为false。"有什么办法能做到我想做的吗?
function() { return false; }
创建一个类型为Closure
的对象,类似于new
的其他类类型,比较以下代码:
$func = function() { return false; };
$func
现在是一个对象。每个对象在if
子句中返回true。所以
if ($func)
{
# true
} else {
# will never go here.
}
你可能想这样做:
if ($func())
{
# true
} else {
# false
}
,它将调用闭包对象$func
并给出它的返回值。
这两个值都为真。
你需要让函数执行才能在if语句中使用它。
试试这个:
$q = function() { return false; };
if ($q()) { //should not go here.
echo $q();
}
else {
echo 'false';
}
演示:http://codepad.viper - 7. - com/osym1s
PHP的闭包是作为Closure
类型的hack - object实现的。你的代码实际上是实例化这个类的一个对象,并把它赋值给$q。在PHP中,赋值的结果就是所赋的值,因此实际上您的代码可以简化为
if (new Closure()) { ... }
调用echo
时没有执行闭包,因此它试图打印出闭包,而不是闭包的结果:
echo $q();
您正在创建一个匿名函数,但从未执行它。当你测试$q = function() { return 'foo'; }
时,你所说的是"将这个匿名函数的引用分配给$q,如果$q不为空,则通过此测试"(PHP不是很有趣吗?)
在测试和回显$q
之前,需要调用闭包并将其结果赋值给$q
。