A small comparison just cost me half an hour of valueable time.
In an ongoing series, I shall present another PHP WTF: **The Boolean paradox**.
// ...
public function setStamp($tm)
{
if ('NOW' == $tm)
$this->stamp = date('Y/m/d');
else if (is_int($tm))
$this->stamp = (0 == $tm ? '0000-00-00' : date('Y/m/d', $tm));
}
//...
$foo->setStamp(0);
echo $foo->stamp;
// Output: 2012/08/10
As you can see, the example above **should** output “0000-00-00” but gives us the current date. Let us disect, shall we?
$a = (int) 0;
$b = 'NOW';
// Let the tests commence...
if ($a == $b)
print "a equals b\n";
if ($a)
print "a is TRUE\n";
else
print "a is FALSE\n";
if ($b)
print "b is TRUE\n";
else
print "b is FALSE\n";
Output ([see this codepad][1]):
a equals b a is FALSE b is TRUE
We shall conclude `FALSE == TRUE` in PHP. Q.E.D.
[1]: http://codepad.org/yn2pW5yW
Well, the conclusion is not exactly true. 🙂
… would be correct.
Because of PHP weak typing all comparisons between an integer and a string will lead to a type cast of the string into an integer.
And by definition if a string does not start with something number-like it will be treated as 0. See http://www.php.net/manual/en/language.types.string.php#language.types.string.conversion
I would recommend writing a separate
resetStamp()
method and remove this special case from thesetStamp()
method.You’re right Phil, though the codepad snippet already contradicts my presumptuous conclusion (look at the last line). IMHO it’s just another flaw resulting from this language having no specs at all. The actual paradox is in PHP evaluating the string as
TRUE
if it’s used as a single argument toif
but is implicitly cast to a “non-true” value if used against another non-string value for comparison. There just seems to be no logical reason behind this.But hey, that’s how we earn our rep on Stackoverflow with, right? Trying to make sense of these incoherencies for others…