ID:               43304
 Comment by:       drm at melp dot nl
 Reported By:      ken at smallboxsoftware dot net
 Status:           Open
 Bug Type:         Feature/Change Request
 Operating System: ALL
 PHP Version:      5.2.5
 New Comment:

Though documented (http://www.php.net/language.operators, quote "If you
compare two numerical strings, they are compared as integers."), this is
indeed unexpected behaviour (and thus a bug)

This bug will probably be closed and denoted as "sorry, documented
feature", but I think this is really a candidate for revision in any
next major PHP version.

Comparison should always feel intuitive, and PHP has made the move
towards more "secure" defaults. This falls (imo) under the same
category. Please witness following example.

client side code:
<form ...>
   <input type="radio" value="0" name="selection" /> No selection
   <input type="radio" value="whatever" name="selection" /> whatever
selection
   (...)
</form>

server side code:
if ( $_GET['selection'] == 0 ) {
   echo '<p>Please make a selection!</p>';
} else {
   // process request
}

Though the example does not imply any security issues, they are not
unimaginable. Please reconsider the behaviour of the comparison
operator.

My suggestion:
Implement (and document!) the following:
Any left side of the comparison is only cast to number if the right
side doesn't fail to. Casting to number is considered successful, if and
only if the string would syntactically be a number in the PHP
Therefore, the string should match the following:

http://php.net/language.types.integer 
http://php.net/language.types.float

[At both pages, see the "formal" definition of both types.]

In any OTHER case, the comparison should act as follows:
If ANY of the sides is of a string type (and of course fails to cast to
number), the other side is cast to string, causing the types to follow
these rules:

integer: the string representation of the integer (e.g. "0", "-4" or
"123")
float: the string representation of the floating point number,
represented in one and only one particular format, preferably just the
%.f format.
boolean: cast to integer, cast to string (so true becomes 1, becomes
"1"; false becomes 0 becomes "0")
array: "array" causing a notice
object: "object" causing a notice, or calling the __toString method if
defined.

The oppposing problem is a non-generic way of handling any other
comparison. As a rule, we could state that any other comparison -if both
sides of different type- is handled the way it is in the current PHP
version. If they are of the same type, the == operator should act the
same as the === operator.

This is, as i am very sure, easily realized. 

Please do not hesitate to ask me any questions through mail.


Previous Comments:
------------------------------------------------------------------------

[2007-11-15 16:27:02] ken at smallboxsoftware dot net

Description:
------------
Casting during comparison should only happen if values of different
types are being compared. 

For example: "42" == "+42" should not return true. 

This result is not very intuitive and probably leads to a number of
subtle errors in various scripts. 

Reproduce code:
---------------
<?php

echo "Should Return False:".("400" == "+400")."<BR>";
echo "Should Return False:".((string) "400" == (string)
"+400")."<BR>";
echo "Does Return False:".("400" === "+400")."<BR>";

?>



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


-- 
Edit this bug report at http://bugs.php.net/?id=43304&edit=1

Reply via email to