PHP WTF: A PHP Annoyance Posted Every Day
phpwtf.org
phpwtf.org
PHP has many problems. We know this. There are millions of words online that will attest to this fact. The fact is, all these words are for naught if people don't step in and do something about it.
This site is mostly written by chx, one of the core developers of the PHP-based Drupal project. It's not meant to be a bashing of PHP or its authors.I've heard of damning with faint praise, but this is more like faint condemnation...
Name a language with more. I'll wait.
I could only find 2 posts in the website. Wake me up when it has at least a dozen articles.
0 == 'x'
results in bool(true)
Does anyone know the technical reasons for this?"As explained under 'read more', it's because 'test' will be cast to a number for comparison. Since 'test' isn't a number, it becomes 0, which is equivalent."
If you can keep it from devolving into thedailywtf.com then you'll have a very loyal reader in me. I work in PHP and I would love to hear a list of valid frustrations instead of the general PHP bashing.
"It's not meant to be a bashing of PHP or its authors."
And if so, does anyone understand how that site isn't mean to be a bashing of PHP? I mean, he's free to bash it if he wants, but does that even make sense?
echo "<?php if (0 == 'test') echo 'true???'; ?>" | php # => "true???"As it stands, PHP's equality operator is not an equivalence relation because it's not transitive. This is deeply unintuitive and logic-defying.
Concepts and algorithms are universal. Operators and keywords are not.
Luckily, this is such a common need when learning a language that this information is kept all together in a tidy tabular way.
Because without it, I'd probably whip up an index.php and write something like print 'Welcome, ' + user.firstName;, get frustrated by parse errors, then by runtime errors, then write some impassioned comment about how deeply unintuitive it is to require prefixed variables and how using a dot for concatenation instead of a plus sign or ampersand is simply logic defying.
And that same table that explains concatenation and scope resolution is also going to give me a simple treatment on the == and === operators in this weakly typed language.
PHP is not an elegant language and given the choice, I'd nearly always prefer to be writing something else. But I took my time to respond to this because there's enough wrong with PHP that we don't need to resort to hyperbole to bash it.
NULL != "0" == false == NULL == 0 == "false" == true
is going to be simple.To avoid implicit type coercion, use the identity operators === and !==.
Of course, the code you posted doesn't parse without adding parens. And when you do, it becomes much more obvious what it's doing and why.
I've worked on some very large web apps (mostly C#, Python and PHP) and I can't recall ever really being foiled by php's implicit casting.
Just out of genuine curiousity, can you share an example where this caused a problem that you had to debug?
And if php implicit casting did somehow cause you problems, surely it was fixed by changing it from equality to identity?
So in summary... this could potentially cause a bug, but probably not, and if it does, it would be a consistent bug, and it would be fixed by a single keystroke.
Why, again, are we talking about this?
== is the type coerce/cast and then compare operator.
I agree with you about the way strings get converted to int instead of the other way around. I believe this is a backwards compatibility issue, and if they could change it they would, but it's too late.
It's also because of 1 == "01" would be false otherwise. And if you think "01" is strange you forget that all input to a php program comes from web forms, and is always a string.
1 == '01' --> true
0 == 'x' --> false
1 == '1' --> true
true == 'asdf' --> false
'-2' == 2 --> true
'-2' == 0 --> false
Seems like in javascript, the coercing is much more sane. In php, all of the above statements would end up true.
'\t\r\n' == 0 --> true
And not transitive: "false" == "0" --> false
"0" == 0 --> true
0 == false --> true
false == "false" --> false
It's basically impossible to make a loosely typed equality perfect.PHP is much more strict about the rules used when doing the comparison, javascript is more loose. It tries to guess.
When comparing a string to a number, if the string looks like a number it's converted to one. But if it doesn't, then instead the number get converted to a string.
This works well most of the time - but not always, since it can surprise you. PHP is more strict, so it doesn't work as often, but it fails more consistently, so it's easier to find the problem.
Another example:
"1" == "01" --> false
"01" == 1 --> true
1 == "1" --> true12 == parseInt('012')
returns false. :)