PHP and Numerical Strings

Take a look at the following two combinations of letters and numbers that make up product codes for a particular company:

608E-4234

272E-3063

To you and I, they look completely different right? I mean the only thing they have in common is their length and the fact they both have “E-” somewhere near the middle. Want to guess what happens when you compare those strings within PHP using its == operator?

<?php
if ("608E-4234" == "272E-3063") {
    echo "These strings match.";
} else {
    echo "These strings do not match.";
}

Yep, you guessed it. The string “These strings match.” is printed. Any PHP developer worth his/her salt should know about the === operator, but most of us only use it when we need to ensure something matches something else in its value AND type. For example:

<?php
var_dump( "1" == 1 ); // Returns true
var_dump("1" === 1); // Returns false because "1" is a string and 1 is an integer
var_dump(1 === 1); // Returns true because both value AND type match
var_dump("" == 0); // Returns true

Based on the sample var_dump() calls above we can deduce that the == operator performs a ‘loose’ comparison, while the === operator performs a ‘strict’ comparison. So why is true returned when we compare two operands of the same type (strings) using ==?

Numerical Strings

Those of you coming from a language like C/C++, Java and other strictly typed languages will be thinking to yourself “Numerical what now?”. Well here’s the gotcha: When PHP sees a string that happens to look like a number in a loose comparison, it’ll turn that string into a number and then compare numerically. The rationale behind this is so that code in the first var_dump() call in the sample above works. It saves the developer having to convert the types of their variables if they’ve been populated from an external source e.g a form submission.

You may still be wondering to yourself that despite all of this, the two product codes we looked at above are quite clearly not numerical strings so why is PHP turning them into numbers?

Floating Point Format

It turns out the two product codes above look like floating point format numbers. Wikipedia describes the format as a “set of representations of numerical values and symbols”, so it’s a way of representing large floating point numbers. Because the two product codes looked like this, PHP converted them to floats, and because they are both too small they were converted to 0 so when we check 608E-4234 == 272E-3063 the actual comparison we’re doing is 0 == 0 which we know is true.

Conclusion

When comparing strings you have two choices. Use the strcmp() function (or strcasecmp() for a case-insensitive comparison), or the triple equals operator. I personally prefer the triple equals operator because it saves the overhead of a function call.

Have you ever been stung by the double equals operator or any other kind of PHP sadness? Let me know in the comments below!


Post Meta

Filed under: Code
Tags:

About the author


Comments