The Boolean paradox
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.
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 | // ... 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):
a equals b a is FALSE b is TRUE
We shall conclude FALSE == TRUE
in PHP. Q.E.D.
Phil said:
Aug 11, 12 at 12:15 amWell, 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.goreSplatter said:
Aug 15, 12 at 7:43 pmYou’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…