5 ms·
'foobar' is coerced into a number, which fails for the obvious reason. So it becomes 0, which means the expression is "0 == 0". Terrible, terrible, behaviour
by stevekemp 6y ago
'foobar' is coerced into a number, which fails for the obvious reason. So it becomes 0, which means the expression is "0 == 0".
Terrible, terrible, behaviour but there are lots of similar examples in PHP because it evolved over time rather than being designed as-is. Some of these things are being fixed over time, like this very example, others can't/won't be.
- scaladev 6y agoAnd people say C++ is a complicated language.
- will4274 6y agoYes because ('0' == 32) returning true makes more intuitive sense. There are languages without type coercion for comparisons (e.g. OCaml), but C++ isn't one of them.
- sleavey 6y agoI see. This change prompts me as something that could break a lot of code running on web servers where the sysadmin updates to PHP8 assuming it will be backwards compatible. I wonder if they did any code searching to see how widely used such expressions are in the wild.
- daneel_w 6y agoIn the absence of strict type checking it would be terrible, but == performs a loose comparison, and "foobar" cannot cast to any other number than 0. Perl will go about it the exact same way. Contrast this against strict comparison, "0" === 0, which will evaluate as false.
- hypertele-Xii 6y agoMaybe "foobar" should evaluate to NaN.
- _-___________-_ 6y agoDoes PHP have separate int and float types? NaN is a float value and I would expect 0 to be an int.
- ragnese 6y agoIt does
- xeeeeeeeeeeenu 6y ago>Perl will go about it the exact same way. No, Perl is completely different and IMO it's the only mainstream dynamically typed language that has sane comparison operators. Perl has two sets of operators, numeric (==, +, *, <, >, <=> etc.) and stringwise (eq, ., lt, gt, cmp etc.). You can think of them as explicit (but concise) casts. For example, Perl's $foo eq $bar is roughly equivalent to Python's str(foo) == str(bar). It is true that "foobar" == 0 returns true in Perl but, as I showed above, it does that for a completely different reason.
- Zancarius 6y ago> Terrible, terrible, behaviour but there are lots of similar examples in PHP So true. One I ran into recently was comparing hashes that start with '0e' and contain only a numeric component after that prefix. Failure to use the identity operator means that you can have two different hashes returning... equality. PHP apparently thought it a good idea to coerce that into 0 raised to an exponent, which of course always yields zero. e.g.: php > var_dump('0e41235843934' == '0e61193475532'); bool(true) Yeah, I know: The correct (and only) way to write this is to use the identity operator (===) but it's not at all intuitive. For those of us who are used to this it's fine since it's a force of habit, but for those who aren't it'll lead to unexpected behaviors. The only saving grace is that the quality of PHP code out there has been slowly (slowly!) improving over time, thanks in part to composer and ecosystem/cultural changes. But it's also not outside the realm of possibility that someone won't eventually forget to add an extra '=' and induce a very difficult bug to isolate...
- jontro 6y agoIs this fixed in php 8? I did not think this was possible as there is no type coercion and not well documented. [1][2] Noticed "0.2" == "0.20" as another example [1] https://www.php.net/manual/en/language.operators.comparison.php https://www.php.net/manual/en/language.operators.comparison.... [2] https://www.php.net/manual/en/language.types.type-juggling.php https://www.php.net/manual/en/language.types.type-juggling.p...
- Zancarius 6y ago> Is this fixed in php 8? I don't know. It's one of those cases where fixing it to do the "right" thing would potentially break a lot of software depending on this sort of erroneous behavior. Part of me wants to say "I hope so" and part of me is kinda terrified at what might happen if they did. Shouldn't be difficult to fix, but it would definitely take some time. Someone should know if there's a decent linter that would pick this up to make it easier to fix, I would imagine! > I did not think this was possible as there is no type coercion and not well documented. I think when applying the equality operator (==) in lieu of the identity operator (===) between strings PHP uses heuristics to decide what to do. If it looks like a number, it coerces it into an int or a float. As an example: php > var_dump('1e12' == 1e12); bool(true) As ridiculous as I think it is, I also take the approach that it's just what PHP does. Weird, maybe a bit eccentric, probably a contributor to difficult-to-find bugs, but it's just something we have to keep in mind. Perhaps I'm feeling charitable because it's Thanksgiving!