Go4Expert

Go4Expert (http://www.go4expert.com/)
-   PHP (http://www.go4expert.com/articles/php-tutorials/)
-   -   String Comparison Gotchas in PHP (http://www.go4expert.com/articles/string-comparison-gotchas-php-t5369/)

pradeep 21Jul2007 11:13

String Comparison Gotchas in PHP
 
Recently, an obscure detail in the way PHP processes strings came to my attention.

This is processed by code that checks for simple lists (like 1. blah 2. blah, or - blah - blah, etc.). However, an innocent call to in_array($x, array('1.', '0.')) had surprising and unexpected results: our friendly PHP determined that '01' was in the array('1.', '0.')!! This is of course patently false, and made little to no sense until I realized that unlike my previous understanding (when comparing an integer to a string, the string is converted to an integer), PHP actually converts all numeric-like strings into integers when comparing them, so that this code emits bool(true):
PHP Code:

<?php
var_dump
('01' == '1.');
?>

This, of course, seems completely counter-intuitive to me, as I would instead use this code if I wished to check a string for numericness:
PHP Code:

<?php
var_dump
('01' == 1);
?>

and continue on my way. What this actually means is that PHP is imposing a new set of rules upon those of us who wish to simply compare our strings in peace. Note that in ANY situation that you have input from uncontrolled sources, and wish to check for comparison to a numeric string, you MUST do one of the following:
  1. use === instead of ==. This will enforce type checking, so that strings are compared as strings
  2. use the 3rd parameter of in_array(), and set it to true
  3. use strcmp() or one of its cousins
If you follow these three rules every time that you compare two strings that should not be compared as numbers, you will be OK.

Note that if you ignore these rules, it could lead to serious security implications, as ==/in_array() will unexpectedly return true in cases where it should not.

Also note that switch/case suffer from the same deficiency, and if there is any chance you will need something like "case '1' :" then you should be using a different system like "if ($a === '1') then blah elseif()..."

In my humble opinion, this auto-conversion is dangerous, but as with many useful features that are so flexible, there is a large precedent for people thinking it is useful enough to outway the danger. I personally think PHP could retain all the benefits of loose typing while removing the auto-conversion of numeric strings to ints just when comparing two strings with == and we would all live happily ever after, but who am I to talk - I just use the language.

The important thing is that anyone out there using == and in_array() improperly or with the wrong understanding needs to fix their code right away to avoid weird and hard to debug edge case behavior.

LenoxFinlay 24Jul2009 09:55

Re: String Comparison Gotchas in PHP
 
__toString() or not to String

PHP version 5 introduced a handy new magic method, __toString(), which lets you do something to the tune of:
class Person {
private $name;

function __construct($name="John Doe"){
$this->name = $name;
}

function __toString(){
return (string) $this->name;
}
}

$bob = new Person('Bob');

echo $bob; //prints Bob That's nice and convenient. But what if I want to add a little punch:


All times are GMT +5.5. The time now is 16:32.