6

I was working on some data parsing code while I came across the following.

$line = "100 something is amazingly cool";
$key = 100;

var_dump($line == $key);

Well most of us would expect the dump to produce a false, but to my surprise the dump was a true!

I do understand that in PHP there is type conversion like that:

$x = 5 + "10 is a cool number"; // as documented on PHP manual
var_dump($x); // int(15) as documented.

But why does a comparison like how I mentioned in the first example converts my string to integer instead of converting the integer to string.

I do understand that you can do a === strict-comparison to my example, but I just want to know:

  • Is there any part of the PHP documentation mentioning on this behaviour?
  • Can anyone give an explanation why is happening in PHP?
  • How can programmers prevent such problem?
mauris
  • 42,982
  • 15
  • 99
  • 131
  • == does numerical comparison I think, and when you take and string and convert it to a number if it begins with a number, it uses that number. If it doesn't probably return something like NaN. – rubixibuc Feb 13 '12 at 08:53
  • Most of us would expect this.... when casting a string to an integer (as happens when comparing a string with a number), PHP stops at the first non-numeric digit it encounters, in this case the space between 100 (all digits) and "something". SO 100 is the resultant value. – Mark Baker Feb 13 '12 at 08:54
  • See http://stackoverflow.com/a/8672423 – Gumbo Feb 13 '12 at 08:54
  • http://php.net/manual/en/language.operators.comparison.php – rubixibuc Feb 13 '12 at 08:54
  • @mark yes most of us would expect a conversion when performing arithmetical operations, but in a comparison one? – mauris Feb 13 '12 at 08:55
  • This is all fully documented in the PHP manual, see the section entitled "String conversion to numbers" on page http://www.php.net/manual/en/language.types.string.php for details of string->numeric casting, and the table of "comaprison with various types" on page http://php.net/manual/en/language.operators.comparison.php for the explanation that string/numeric comparison converts the string to a numeric – Mark Baker Feb 13 '12 at 08:58

2 Answers2

4

If I recal correcly PHP 'casts' the two variables to lowest possible type. They call it type juggling.

try: var_dump("something" == 0); for example, that'll give you true . . had that bite me once before.

More info: http://php.net/manual/en/language.operators.comparison.php

the JinX
  • 1,950
  • 1
  • 18
  • 23
  • The PHP manual now describes type juggling at http://php.net/manual/en/language.types.type-juggling.php which in turn links to a section about string conversion to numbers at http://php.net/manual/en/language.types.string.php#language.types.string.conversion – Josip Rodin Oct 02 '15 at 14:30
1

I know this is already answered and accepted, but I wanted to add something that may help others who find this via search.

I had this same problem when I was comparing a post array vs. keys in a PHP array where in my post array, I had an extra string value.

$_POST["bar"] = array("other");

$foo = array(array("name"=>"foobar"));

foreach($foo as $key=>$data){
    $foo[$key]["bar"]="0";
    foreach($_POST["bar"] as $bar){
        if($bar==$key){
            $foo[$key]["bar"]="1";
        }
    }
}

From this you would think that at the end $foo[0]["bar"] would be equal to "0" but what was happening is that when $key = int 0 was loosely compared against $bar = string "other" the result was true to fix this, I strictly compared, but then needed to convert the $key = int 0 into a $key = string "0" for when the POST array was defined as array("other","0"); The following worked:

$_POST["bar"] = array("other");

$foo = array(array("name"=>"foobar"));

foreach($foo as $key=>$data){
    $foo[$key]["bar"]="0";
    foreach($_POST["bar"] as $bar){
        if($bar==="$key"){
            $foo[$key]["bar"]="1";
        }
    }
}

The result was $foo[0]["bar"]="1" if "0" was in the POST bar array and $foo[0]["bar"]="0" if "0" was not in the POST bar array.

Remember that when comparing variables that your variables may not being compared as you think due to PHP's loose variable typing.

amaster
  • 1,915
  • 5
  • 25
  • 51
  • Maybe it's just me, but your example is too convoluted for its own good. The issue seems to be that you define `$foo` as an associative array nested within a regular array, but then use the associative array expression `($key=>$data)` to parse the regular array. If you have to have this nesting in the data, why not also nest that loop within another one that would handle the regular array? – Josip Rodin Oct 31 '15 at 14:23