why is '01' == '1.'?

php.internals

Greg Beaver

20 years ago
Hi all, I realize that 1 == '01' and 1 == '1.', but why is this next code also bool(true)? <?php var_dump('1.' == '01'); ?> In this case, a string is explicitly being compared to a string, and yet both are being converted to an int prior to comparison. I can understand that implicit type conversion is needed when comparing strings to ints, but this can be dangerous. phpDocumentor, for instance uses this code: if (in_array(substr($ltrimword, 0, 2), array('1.', '0.'))) and assumes that it will only match either '1.' or '0.', but in fact, it will match '01', '1.', '0.', '00', and as such if this happens to be encountered, it can cause an infinite loop in phpDocumentor eating up all memory (bad - will be fixed in next release). Of course, I can fix this by using === for each element instead of in_array(), but this is extremely non-intuitive and dangerous behavior in the underlying PHP implementation. The manual says nothing about auto-conversion of strings to ints when comparing two strings that satisfy is_numeric(). My question is whether this is a documentation or an internal PHP error? Greg

Jani Taskinen

20 years ago
bool in_array ( mixed needle, array haystack [, bool strict] ) See the last parameter? :) --Jani On Wed, 14 Dec 2005, Greg Beaver wrote:

Stefan Walk

20 years ago
See http://bugs.php.net/bug.php?id=23110 It's definitely a gotcha, especially if you use switch(){}, as there is no way to do strict type checking there. Regards, Stefan

Ron Korving

20 years ago
This may sound like a screwed up idea, and I'm not even sure if I would support it, but just something that went through my mind: A 2nd (flag) parameter for switch could do miracles: switch ($var, SWITCH_STRICT) { } and could be used for more than just strict checks: switch ($var, SWITCH_STRICT | SWITCH_REGEXP) { case '/^[0-9]+$/': echo 'a number'; break; } or perhaps with byte-flags like with fopen(): switch ($var, 'r') { case '/^[0-9]+$/': echo 'a number'; break; } Just an idea, and perhaps gross, but very practical if you ask me. - Ron "Stefan Walk" <stefan.walk@gmail.com> schreef in bericht news:4858f9d90512150059x71eec489t@mail.gmail.com... See http://bugs.php.net/bug.php?id=23110 It's definitely a gotcha, especially if you use switch(){}, as there is no way to do strict type checking there. Regards, Stefan

Greg Beaver

20 years ago
Stefan Walk wrote:
> See http://bugs.php.net/bug.php?id=23110 > > It's definitely a gotcha, especially if you use switch(){}, as there > is no way to do strict type checking there.
Please reconsider the decision to leave this bug open in PHP, any unexpected behavior in an operator as fundamental as == is VERY dangerous, and if used improperly could lead to security holes (i.e. unexpectedly, input that does not match could match a strict filter based on ==) I understand the rationale behind loosely typed comparison, and use it myself, but this is beyond loosely typed, it is explicitly changing type in an irrational way, as it only applies in certain cases. Greg

Zeev Suraski

20 years ago
At 16:33 15/12/2005, Greg Beaver wrote:
>Stefan Walk wrote: > > See http://bugs.php.net/bug.php?id=23110 > > > > It's definitely a gotcha, especially if you use switch(){}, as there > > is no way to do strict type checking there. > >Please reconsider the decision to leave this bug open in PHP, any >unexpected behavior in an operator as fundamental as == is VERY >dangerous, and if used improperly could lead to security holes (i.e. >unexpectedly, input that does not match could match a strict filter >based on ==) > >I understand the rationale behind loosely typed comparison, and use it >myself, but this is beyond loosely typed, it is explicitly changing type >in an irrational way, as it only applies in certain cases.
Greg, A lot of thought has been put into the current behavior, which was decided upon probably around 8+ years ago. While I'm not positive we made the right decision back then (even though I think we did) - changing this behavior is completely out of the question. It's not a bug, it's a well-documented feature ("strings that look like numbers behave like numbers"), and changing it would effect an enormous amount of applications. In order to change such a fundamental behavior there have to be clear-cut compelling reasons, and no compelling reasons against - which is clearly not the case. Zeev

Jason Sweat

20 years ago
On 12/14/05, Greg Beaver <greg@chiaraquartet.net> wrote:
> In this case, a string is explicitly being compared to a string, and yet > both are being converted to an int prior to comparison. I can > understand that implicit type conversion is needed when comparing > strings to ints, but this can be dangerous. phpDocumentor, for instance > uses this code: > > if (in_array(substr($ltrimword, 0, 2), array('1.', '0.')))
Perhaps if (preg_match('/^[10]\./',$ltrimword)) would be both more concise and express your intent better? Regards, Jason http://blog.casey-sweat.us/

Hans Melis

20 years ago
Greg Beaver wrote:
> Hi all, > > I realize that 1 == '01' and 1 == '1.', but why is this next code also > bool(true)? > > <?php > var_dump('1.' == '01'); > ?> >
That is pure logic... a == b and a == c implies by the rules of logic that b == c
-- Hans avast! Antivirus: Outbound message clean. Virus Database (VPS): 0550-3, 15/12/2005 Tested on: 15/12/2005 18:19:04 avast! - copyright (c) 1988-2005 ALWIL Software. http://www.avast.com

colder.ch

20 years ago
No, this rule of logic can't be applied : 2 == true and true == 10, but 2 != 10 It all depends on the types of the compared values. Hans Melis wrote:
>a == b and a == c implies by the rules of logic that b == c > >
-- Etienne Kneuss http://www.colder.ch/ colder@php.net

M. Sokolewicz

20 years ago
actually, you're right in that (colder.ch) since what happens here is a conversion. This applies to all these 'logic cases' posted. When something is converted to something else, as part of a process, you can't state that the process returns unique results (meaning the result always points back to the same input), and as such you can't state a lot of various things posted in this thread. But this is all OT, and really should be moved off the list, or at least to the generals list. - tul colder.ch wrote:

Carl P. Corliss

20 years ago
Greg Beaver wrote:
> Hi all, > > I realize that 1 == '01' and 1 == '1.', but why is this next code also > bool(true)? > > <?php > var_dump('1.' == '01'); > ?>
http://us3.php.net/manual/en/language.types.string.php#language.types.string.conversion Also, if you want strict type checking, try using === ....
-- Carl