views:

704

answers:

3

I'm really confused as to why this operation works. Can someone explain it?

$test1 = "d85d1d81b25614a3504a3d5601a9cb2e";
$test2 = "3581169b064f71be1630b321d3ca318f";

if ($test1 == 0)
  echo "Test 1 is Equal!?";
if ($test2 == 0)
  echo "Test 2 is Equal!?";

// Returns: Test 1 is Equal!?

For clarification, I am trying to compare the string "0" to the $test variables. I already know to fix the code I can just enclose (as I should have) the 0 in ""s

I'm wondering if this is a PHP bug, a server bug, or somehow a valid operation. According to http://us3.php.net/types.comparisons this should not have worked.

Edit: Scratch that, apparently it does mention that Loose comparisons between string and 0 is true. But I still don't know why.

Edit 2: I've revised my question, why does the $test2 value of "3581169b064f71be1630b321d3ca318f" not work?

+2  A: 

The == operator is a loosely-typed comparison. It will convert both to a common type and compare them. The way strings are converted to integers is explained here.

Note that the page you linked to doesn't contradict this. Check the second table, where it says that comparing the integer 0 to a string "php" using == shall be true.

What happens is that the string is converted to integer, and non-numeric strings convert to 0.

You probably want:

if ($test1 === "0")

Notice the use of triple equals instead of a double equals.

thomasrutter
+1  A: 

After some investigation, it turns out aidan from the PHP manual mentioned that any strings that do not start with a number will be converted to 0 when casted as an integer.

This means that:

("php" == 0) === true
("1php" == 0) === false

Very annoying and not well documented. It was at the bottom of the comments on the type comparison page.

St. John Johnson
Yeah, figured that was it. Poor documentation indeed.
Paolo Bergantino
I don't think it's poor documentation at all. Implicit type conversion is a fundamental of PHP which is explained very well in the manual in the section on Types, particularly the Type Juggling section. == is a loosely typed comparison; using === instead can help prevent confusing situations.
thomasrutter
See also "String Conversion to Numbers" at http://us3.php.net/manual/en/language.types.string.php#language.types.string.conversion
thomasrutter
+4  A: 

From the PHP manual:

String conversion to numbers

When a string is evaluated in a numeric context, the resulting value and type are determined as follows.

The string will be evaluated as a float if it contains any of the characters '.', 'e', or 'E'. Otherwise, it will be evaluated as an integer.

The value is given by the initial portion of the string. If the string starts with valid numeric data, this will be the value used. Otherwise, the value will be 0 (zero). Valid numeric data is an optional sign, followed by one or more digits (optionally containing a decimal point), followed by an optional exponent. The exponent is an 'e' or 'E' followed by one or more digits.

Assaf Lavie
Still don't think it should convert to a 0, or at least if it starts with a number not to convert to a decimal if there are erroneous characters in the string.
St. John Johnson
PHP has no "NaN" type like Javascript (another loose-typed language) so it pretty much has to convert to 0 as there would be no other way (converting to NULL wouldn't work cos NULL also converts to 0). I think the answer is not to use a loose comparison (==), or to validate the string first.
thomasrutter