The issue of PHP strings equaling zero has come up a few times recently. Here’s a specific example:
[sourcecode lang=”php”]
if ( ‘php’ == 0 ) {
echo "Equals zero!n";
} else {
echo "Not equal to zeron";
}
[/sourcecode]
Running that will display Equals zero!
, which at first glance probably doesn’t make much sense. So what is going on here?
The first thing to look at is that the conditional involves two different variable types. The first is 'php'
, which is a string, and 0
which is an integer. Because we are using the ==
comparison operator instead of ===
there will be some type juggling. If we had used ===
instead the comparison will evaluate to false since there would be no type conversion.
For this comparison PHP will be using the integer context. That means our string 'php'
is going to be converted into an integer first, then the comparison will happen. You can picture this first step via:
[sourcecode lang=”php”]
var_dump( (int) ‘php’ );
[/sourcecode]
Which will show int(0)
. That isn’t a surprise given what we saw in the original code example. Just to make things more interesting, PHP strings when cast as an integer only sometimes become zero.
Now is a good time to point to the PHP documentation on the subject, specifically the “String conversion to numbers” section of the Strings page on php.net. That is where the rules of string conversion are outlined:
When a string is evaluated in a numeric context, the resulting value and type are determined as follows.
If the string does not contain any of the characters ‘.’, ‘e’, or ‘E’ and the numeric value fits into integer type limits (as defined by PHP_INT_MAX), the string will be evaluated as an integer. In all other cases it will be evaluated as a float.
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.
A small modification to the orignal example demonstrates these rules in action:
[sourcecode lang=”php”]
if ( ‘7php’ == 0 ) {
echo "Equals zero!n";
} else {
echo "Not equal to zeron";
}
[/sourcecode]
This outputs Not equal to zero
, because '7php'
when converted to an integer gets a value of 7 instead of 0.
Even after understanding the steps that are involved there is still one piece that bothers me. The choice to use an integer context for things like 'php' == 0
. At first glace my expectation would be to have it evaluated in a string context, essentially something like 'php' == '0'
. It isn’t clear to me why PHP opted to use the integer context instead.
One final word on the scope of this issue. While I still think it is odd that the string gets cast as an integer instead of the other way around, I don’t think this is a big deal. I can’t recall a single time where I’ve ever run into this issue in a PHP app. I’ve only seen it come up in contrived examples like the ones above.