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

From: Date: Tue, 27 May 2014 15:41:55 +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-185936@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:

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';
}
?>


Previous Comments:
------------------------------------------------------------------------
[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).

------------------------------------------------------------------------
[2013-10-22 18:42:18] mirroredfate at gmail dot com

> It's not a problem -- it's a feature, and it's documented at the address
> I've just quoted

And I could document a webserver sometimes crashing when you click a button and call it a
"feature", but that doesn't make it so.

This is clearly counter-intuitive behavior and should be beaten to death with an iron rod after
being water-boarded. It is terrible. If you are defending this, you should probably take a long,
hard look at your life and your principles.

Making zero equal any string is just wrong. I completely goes against how PHP operates in every
other instance, and no doubt causes developers no end of distress and frustration. It's a
feature like how getting beaten up in a dark alley is a feature of that alley.

This needs to be fixed, people.

------------------------------------------------------------------------


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


Thread (29 messages)

« previous php.bugs (#185936) next »