Req #39579 [Com]: Comparing zero & string values in boolean comparison has unexpected behaviour

From: Date: Wed, 28 May 2014 13:25:21 +0000
Subject: Req #39579 [Com]: Comparing zero & string values in boolean comparison has unexpected behaviour
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-185949@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=39579&edit=1 ID: 39579 Comment by: tom at r dot je Reported by: iain at workingsoftware dot com dot au Summary: Comparing zero & string values in boolean comparison has unexpected behaviour Status: Not a bug Type: Feature/Change Request Package: Variables related Operating System: FreeBSD 6.1 PHP Version: 5.2.0 Block user comment: N Private report: N New Comment: To expand on my point above: 0 == '0' //TRUE Here, 0 and '0' are equivalent. However: 0 == 'a'; //TRUE '0' == 'a'; //FALSE Here, 0 and '0' are not equivalent which is very inconsistent. If 0 is equivalent to '0' and 0 is equivalent to 'a' than it logically follows that '0' is equivalent to 'a'; which is clearly not the case, and nor should it be to fix this logical contradiction the only option is to make 0 and 'a' not equivalent. As for the problems presented above about actually implementing a change, why not do what's been done before and add an INI setting (settable via ini_set). Any scripts which do rely on this broken functionality can just call ini_set for compatibility with the old operator. Previous Comments: ------------------------------------------------------------------------ [2014-05-27 15:41:55] tom at r dot je I have to agree with the above, this is illogical and confusing. What just caught me out was an internal conversion from string to int which triggered the bug (and yes I definitely consider this a bug.) Try this: <?php $arr = array('0' => 'Abc'); $keys = array_keys($arr); if ($keys[0] == 'foo') { echo 'String\'s equal'; } ?> ------------------------------------------------------------------------ [2013-11-07 23:18:58] duerra at yahoo dot com I'm sorry, but this is just silly. This has to be one of PHP's most glaring weaknesses. While it can be understood, this does NOT make it logical. In fact, unless you have a very firm understanding of both how PHP casts strings to integers, and always explicitly know or cast your types (which PHP's design largely tries to avoid having users worry about), this becomes an issue that can hit somebody out of nowhere, unexpectedly, and leave them wracking their brains trying to sort out. root@host:/bright/Bright# php -r "echo (0 == 'string') ? 'TRUE' : 'FALSE';" TRUE root@host:/bright/Bright# php -r "echo (0 == '1string') ? 'TRUE' : 'FALSE';" FALSE root@host:/bright/Bright# php -r "echo ('0' == 'string1') ? 'TRUE' : 'FALSE';" FALSE root@host:/bright/Bright# php -r "echo (1 == 'string') ? 'TRUE' : 'FALSE';" FALSE root@host:/bright/Bright# php -r "echo (1 == '1string') ? 'TRUE' : 'FALSE';" TRUE root@host:/bright/Bright# php -r "echo (1 == 'string1') ? 'TRUE' : 'FALSE';" FALSE I realize and understand that this may never change, but that doesn't make it logical or correct, and in the meantime you're probably allowing more bugs in the wild than you would cause by actually fixing the issue or using one of the other suggestions from this thread (such as throwing a Notice). ------------------------------------------------------------------------ [2013-10-22 21:42:58] mirroredfate at gmail dot com There is another option: when a string casting to an int fails inside a conditional statement, the conditional evaluates to false. >Both of these changes would wreak unspeakable havoc on existing applications, and probably >wouldn't make any tremendous difference overall to the uninitiated. Really? I am genuinely curious as to why anyone would actually use '(0 == 'string') to determine if a string could not be cast to an int. This seems kind of like a "rip the band-aid off" situation to me. Let people know a few patches ahead of time, then go ahead with the change. After all, PHP had no problem removing JSON. The fact that it could cause problems is one of the biggest reasons why one should not design stupid, counter-intuitive stuff the first place. ------------------------------------------------------------------------ [2013-10-22 21:33:09] v dot picture at free dot fr *Sighh* Do I have to open a separate bug report ? Everybody seems to ignore the comment I made about a year ago about the fact that: ((string) "10" == (string) "1e1") => true So okay, ("test" == 0) => true, let's pretend it's a feature (and insult the intelligence of about every PHP developer) but there is no way that a comparison between two strings could end up being evaluated as numbers ! There is clearly something very wrong with that ! ------------------------------------------------------------------------ [2013-10-22 20:45:43] iain at workingsoftware dot com dot au Hi mirroredfate at gmail dot com, I really don't think this should be changed. Take a look at my note above about why this happens, it's because in one case the string is cast as boolean, and in another case cast as an int. Changing this would require either: a) Changing the type that you cast a variable to when you do if($var) to something other than boolean or changing the way that types are cast when comparing a string and an int to each other OR; b) Changing the value that a string is cast to when cast as either a boolean or an int, to be consistent Both of these changes would wreak unspeakable havoc on existing applications, and probably wouldn't make any tremendous difference overall to the uninitiated. HOWEVER, I do think that it would be acceptable to emit a NOTICE when a string is implicitly cast to (int) during a comparison using == and suggesting they use an explicit type cast or strict equals to suppress the notice (see my comments above). ------------------------------------------------------------------------ The remainder of the comments for this report are too long. To view the rest of the comments, please view the bug report online at https://bugs.php.net/bug.php?id=39579 -- Edit this bug report at https://bugs.php.net/bug.php?id=39579&edit=1

« previous php.bugs (#185949) next »