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
bool in_array ( mixed needle, array haystack [, bool strict] )
See the last parameter? :)
--Jani
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
satisfyis_numeric()
. My question is whether this is a documentation or
an internal PHP error?Greg
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
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
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
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
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/
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
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
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:
No, this rule of logic can't be applied : 2 == true and true == 10, but
2 != 10It 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
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