note 91593 deleted from language.operators.comparison by danbrown
| From: | danbrown@php.net | Date: | Thu, 18 Jun 2009 14:03:36 +0000 |
| Subject: | note 91593 deleted from language.operators.comparison by danbrown | ||
| References: | 1 | Groups: | php.notes |
| Request: | Send a blank email to php-notes+get-157060@lists.php.net to get a copy of this message | ||
Note Submitter: php at kennelREMOVEME17 dot co dot uk
----
Quote:
"If you compare an integer with a string, the string is converted to a number. If you compare
two numerical strings, they are compared as integers."
There are a lot of comments discussing the difference between == and ===, and how the latter does a
strict comparison including type, thus allowing you to work around the behaviour described in the
quote above.
However, what is less obvious is that this also applies to the other operators in the list, and this
can lead to unwanted behaviour.
For example:
<? var_dump("51" < "500"); ?>
output: bool(true)
This is because if both strings are numeric they are converted to numbers in order to do the
comparison.
Often this is what you want, but not always. For example if you want to sort an array in
alphabetical order (e.g. "5", "50", "500", "51",
"52", etc.) then the above will not sort correctly. If you are using a manual sort then
they will be sorted numerically ("5", "50", "51", "52",
etc..., "500"). More worryingly, if you use one of the sort() functions then
any wholly numeric entries will be sorted numerically when compared with other numeric entries, but
alphabetically when compared with strings! This leads to an undefined sort order, which may give
different results based on the order the original array was sorted (i.e. which comparisons take
place, and in which order) rather than the actual data in the array.
The workaround is either to add a string character (the same one) to the start of both values, or to
use the strcmp() function.
For example:
<?php
// Instead of:
if ($a < $b) { ... }
// you could use
if ("x" . $a < "x" . $b) { ... }
// or
if (strcmp($a, $b) < 0) { ... }
?>