My goal is to put some complex logic in an if() statement. Let's say I have an array of values and I'm going to execute a bit of code if everything in my array is nonzero. Normally, I could say, $valid = true
, foreach
my array, and set $valid = false
when a zero is found. Then I'd run my code if ($valid)
. Alternatively, I could put my loop into a function and put the function intop my if()
.
But I'm lazy, so I'd rather not muck about with a bunch of "valid" flags, and I'd rather not write a whole new function that's only being used in one place.
So let's say I have this:
if ($q = function() { return 'foo'; }) {
echo $q;
}
else {
echo 'false';
}
I was expecting that the if
gets 'foo'
, which evaluates to true. My closure is committed to $q
and the statement executes. $q
returns string foo
, and 'foo' is printed.
Instead, I get the error Object of class Closure could not be converted to string
.
So let's try this instead:
if (function() { return false; }) {
echo 'foo';
}
else {
echo 'true';
}
I was expecting that my function would return false and 'true' would be printed. Instead, 'foo' is printed.
What is wrong about the way that I'm going about this? It seems like it's saying, "Yep, that sure is a function!" instead of "No, because the function evaluated to false." Is there a way to do what I'm trying to do?
function() { return false; }
creates an object of type Closure
, similar to new
with other class-types, compare the following code:
$func = function() { return false; };
$func
now is an object. Each object returns true in an if
clause. So
if ($func)
{
# true
} else {
# will never go here.
}
You might want to do this instead:
if ($func())
{
# true
} else {
# false
}
which will invoke the Closure object $func
and give it's return value.
Both of those evaluate to true.
You need to make the function execute to use it in the if statement.
Try this:
$q = function() { return false; };
if ($q()) { //should not go here.
echo $q();
}
else {
echo 'false';
}
Demo: http://codepad.viper-7.com/Osym1s
PHP's closures are implemented as a hack - objects of type Closure
. Your code is actually instantiating an object of this class, and assigning it to $q. In PHP, the result of assignment is the value being assigned, so in effect you code boils down to
if (new Closure()) { ... }
You're not executing the closure when you call echo
, thus it's trying to print out the closure, not the result of the closure:
echo $q();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With