When blog posts here slow down as they have over the last few weeks, it’s a good bet I have my head down building something.
I ran across an issue today that I’d worked around in the past, but had never explicitly investigated. It appears that when assigning a variable within a multiple condition check in PHP, if you don’t explicitly look for a value the first item in the expression is cast as a bool.
I particularly use this technique a lot in CodeIgniter, for example when pulling data from $this->input->post('foo')
– a method that will either return semi-sanitized data from $_POST['foo']
or will return false
.
I tested this in PHP 5.3 (built-in version on Snow Leopard).
Here is some sample code that demonstrates this issue, and the workaround.
function foo() { return 'foo'; } function bar() { return 'bar'; } if ($foo = foo()) { echo '<p>Condition <code>$foo = foo()</code> passed</p>'; } var_dump($foo); echo '<hr />'; if ($foo = foo() && $bar = bar()) { echo '<p>Condition <code>$foo = foo() && $bar = bar()</code> passed</p>'; } var_dump($foo); echo '<hr />'; if ($foo = foo() && $bar = bar()) { echo '<p>Condition <code>$foo = foo() && $bar = bar()</code> passed</p>'; } echo '<p>$foo:<br />'; var_dump($foo); echo '<p>$bar:<br />'; var_dump($bar); echo '<hr />'; if (false !== ($foo = foo()) && $bar = bar()) { echo '<p>Condition <code>false !== ($foo = foo()) && $bar = bar()</code> passed</p>'; } echo '<p>$foo:<br />'; var_dump($foo); echo '<p>$bar:<br />'; var_dump($bar);
Here is the output of this code:
Condition $foo = foo()
passed
string(3) “foo”
Condition $foo = foo() && $bar = bar()
passed
bool(true)
Condition $foo = foo() && $bar = bar()
passed
$foo:
bool(true)
$bar:
string(3) “bar”
Condition false !== ($foo = foo()) && $bar = bar()
passed
$foo:
string(3) “foo”
$bar:
string(3) “bar”
Hopefully this will be useful to someone else when they run across this issue.
Know why PHP works this way? Let me know in the comments.
UPDATE: wrapping each expression in parenthesis works around this. See comments for more detailed explanation.