Having this bug on a few version of php, 5.2, I’m on 5.3
Here’s the code:
$value = 0;
if($value == "NOW()")
{
echo 'I think im a NOW(). wtf<br />';
}
if($value == 0)
{
echo "I am a zero<br />";
}
if($value == 'GOD')
{
echo 'There is a god <br />';
}
echo "Now quoting it<br />";
$value = '0';
if($value == "NOW()")
{
echo 'I think im a NOW(). wtf<br />';
}
if($value == 0)
{
echo "I am a zero<br />";
}
if($value == 'GOD')
{
echo 'There is a god <br />';
}
Which outputs:
I think im a NOW(). wtf
I am a zero
There is a god
Now quoting it
I am a zero
Which leaves me puzzled, since it seems a 0 is not actually a 0, unless it’s typed as a string, not an int. Umm, huge bug? This makes me really question alot of code I’ve written.
In this case, I have a 0/1 on/off value, but I check it against various other value possibilities, for a SQL string quoting (home-made associative arrays to sql queries). Been getting a few bugs from users, where a check for SQL keyword.
I can get around it with if(is_int($value)), but it just seems odd where the type of int with a value of 0 is equal to pretty much anything.
Can someone explain that to me? To be honest, this is the first time in my 8 years with PHP, using all sorts of frameworks (cake, ci, also orm), apps, etc I’ve encountered this.
Oh, that would make sense. Now that I think of it, I remember reading about that a long time ago. That’s an odd one. Well, I fixed it by is_int() - which strangely I had done in other functions, I guess just overlooked/forgot about that.
I second using strict comparison when possible. === !==
The loose comparison operators can be really handy in some situations, but they’re liabilities unless you’re real familiar with the rules.
I’ll have to check against that. Right now, this code doesn’t look at anything outside, but that is “right now”.
I have to read up on ===, I’ve used it in limited cases, but never really went into the complete rules of how it worked. I always assumed == was the C equivalent.
Here are the steps that are performed (in order) to perform a loose comparison using the == operator
[list=1][]null == string (convert null to “”)
[]bool or null == anything (convert to bool)
[]object == object (if same class, php4 compares values, php5 has it’s own special object comparison rules
[]string/resource/number == string/resource/number (convert string/resource to a number)
[]array == array (if arrays have same number of members, compare value by value, otherwise less members is smaller)
[]array == anything (array is greater)
[*]object == anything (object is greater)[/list]
Thank you for the detailed reply. I guess that’s the challenge working with a loosely-typed language. I’ve made some adjustments to my code and noted it for the future.
I have never tried to compare objects and arrays with ==, and I’ve been doing this a long time. The thought of it scares me, having null, false, “” and 0 being evaluated to the same thing is bad enough until you get the hang of it.
I use == if my course of action for 0, null, false, and “” is going to be the same (oftentimes this is true). 90% of the time when I’ve needed to detect one of these from the others its been null state, in which case is_null() works. But on those occassions when I need to have the code do something different for each case I resort to ===
Rather than put === all over the place I try to avoid situations where having empty values evaluate to the same thing matters.
And I’ve never needed to compare arrays and objects - not saying that won’t ever come up, but if it did I probably would go for strict comparison because, well yeah - it’s enough of a headache as is.