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

- Thread: https://externals.io/message/21223
- Original archive: https://news-web.php.net/php.internals/21223
- Started by Greg Beaver on 2005-12-15T04:27:39+00:00
- Messages: 11
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #21223 — Greg Beaver — 2005-12-15T04:27:39+00:00

URL: https://externals.io/message/21223#21223

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

---

## #21224 — Jani Taskinen — 2005-12-15T06:59:04+00:00

URL: https://externals.io/message/21223#21224 · In reply to: #21223

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
> satisfy `is_numeric()`.  My question is whether this is a documentation or
> an internal PHP error?
>
> Greg

---

## #21225 — Stefan Walk — 2005-12-15T08:59:26+00:00

URL: https://externals.io/message/21223#21225 · In reply to: #21223

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

---

## #21227 — Ron Korving — 2005-12-15T10:36:23+00:00

URL: https://externals.io/message/21223#21227 · In reply to: #21225

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

---

## #21229 — Jason Sweat — 2005-12-15T12:47:54+00:00

URL: https://externals.io/message/21223#21229 · In reply to: #21223

> 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/

---

## #21230 — Greg Beaver — 2005-12-15T14:33:39+00:00

URL: https://externals.io/message/21223#21230 · In reply to: #21225

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

---

## #21232 — Zeev Suraski — 2005-12-15T14:53:56+00:00

URL: https://externals.io/message/21223#21232 · In reply to: #21230

At 16:33 15/12/2005, Greg Beaver wrote:
>Stefan Walk wrote:
> > […]
>
>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

---

## #21236 — Hans Melis — 2005-12-15T17:19:04+00:00

URL: https://externals.io/message/21223#21236 · In reply to: #21223

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

---

## #21237 — colder.ch — 2005-12-15T17:28:15+00:00

URL: https://externals.io/message/21223#21237 · In reply to: #21236

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

---

## #21238 — M. Sokolewicz — 2005-12-15T17:38:54+00:00

URL: https://externals.io/message/21223#21238 · In reply to: #21237

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 != 10
> 
> It all depends on the types of the compared values.
> 
> 
> Hans Melis wrote:
> 
> 
> > […]

---

## #21240 — Carl P. Corliss — 2005-12-15T20:17:40+00:00

URL: https://externals.io/message/21223#21240 · In reply to: #21223

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
