Edit report at http://bugs.php.net/bug.php?id=43304&edit=1
ID: 43304 Comment by: kissifrot at gmail dot com Reported by: ken at smallboxsoftware dot net Summary: Casting During Comparison Status: Open Type: Feature/Change Request Package: Feature/Change Request Operating System: ALL PHP Version: 5.2.5 Block user comment: N Private report: N New Comment: I agree with that, for example if I have $ric1 = '00001000010000000198358'; $ric2 = '00001000010000000198455'; var_dump($ric1 == $ric2) should return false, not true, just because it's logical. But the current behavior makes PHP somewhat unreliable :( Previous Comments: ------------------------------------------------------------------------ [2008-09-06 23:49:58] drm at melp dot nl 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. ------------------------------------------------------------------------ [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/bug.php?id=43304&edit=1