Comparing Strings in PHP – Mysteries of PHP, Part 2

Don’t use the equality operator (==) to compare strings – use the strcmp() function, or the identity operator (===). In fact, when comparing values in PHP, use the identity operator (===) instead of the equality operator whenever possible. You may have heard that === is faster, since it incurs no type conversions, but some people have argued that it hurts code clarity. According to this theory, you should only use the identity operator when you actually need the two variables to have the same type, as when checking strpos() for the return value “false“. But the fact is that the identity operator is not only faster, it is also clearer. The identity operator says, “These two pieces of data are identical,” whereas the equality operator says, “These two pieces of data, or anything under the sun they could possibly be converted to, are equal.” Which seems like clearer code to you?

If you doubt the importance of this distinction – and I understand why you might – check out the following, rather shocking examples taken from the PHP manual:

if (            0 == 'my string'
  &&            1 != 'my string'
  &&       '+010' == '10.0'
  &&   '  131e-2' == '001.3100'
  && '000e002073' == '0e459239'
  &&       '0xab' == 0253
  &&       '0xab' != '0253'
  &&       '0xab' == '171'
){
  echo 'WTF????';
}

If you run the above code, you will see that all the above examples do indeed evaluate to true. How can that be? It’s because PHP checks every possible conversion of each argument, so it actually tries converting both strings to floats, and if those floats are equal, returns true. Those little e’s are exponent markers, the x’s indicate hexadecimal values, and a leading 0 marks an octal (unless it’s in a string, apparently). As for why the numeral zero is equal to any string … it beats the hell out of me.

In light of these facts, a developer should only ever use == when type-conversion is expected, such as when comparing a form input to a numerical value. Furthermore, we should regard == as expressing this expectation, since, by using the comparison operator, the developer has forced us to check for conversions. Thus, to keep your code clean and self-documenting, stop using ==. Use strcmp() for strings; it’s binary-safe, and expresses the type of your arguments without the need for comments. Use === for everything else.