How can this happen?
var_dump(0=="some string"); // yields true, why?
switch(0) {
case "a":
echo "a"; // <-- we get here, why?
break;
case "b":
echo "b";
break;
default:
echo "def";
break;
}
according to this
0=="some string"
0==(int)"some string"
0==0
true
this also would logical:
0=="some string"
(string)0=="some string"
"0"=="some string"
false
Too Long; Didn’t Read
To sum this up in this rather long post; an implicit conversion from one type to another takes place, if you don’t want this to happen use the more strict
===or an explicit cast.Examples including both can be found further down in this post..
Further reading about type-juggling can be found in the relevant section of the manual, located here.
Will the world will end, is the PHP interpreter is lying to me?
Not really, even though this might be unexpected at first glance it is actually a feature (type-juggling) of the language and it’s often very usable in other situations.
When comparing objects of different types the PHP interpreter needs to find a common ground if they are of different types, naturally it will implicitly try to convert one to the other.
In this case it will try to convert the string “string” into a numeral value.
The below line is equivalent to what you have in your question:
Hmm, wait.. erhm, what!?
Since a conversion from “string” to a numeric value isn’t really possible the implicit conversion will yield
0(as specified by the language).We know that comparing
0to0should comparetrue, and this is exactly what is happening. The below is equivalent to what you have in your question, though it’s more verbose to explain things further.But hey.. HEY, HOLD UP!
“When I use my switch I’m not even calling any comparison-operator, what is going on with that example?”
You don’t, but the internals of the interpreter will when executing your switch-statement.
To get around this problem you will need to explicitly cast either the needle you are searching for, or the values used as labels so that they are of the same type.
Your previous snippet could be written as the below to enable more strict comparison.
What if I don’t want to use this “feature”, what should I do?
Since PHP4 there is a more strict comparison operator;
===.This will not allow an implicit conversion of one of the operands, instead it will first check to see if the operands are of the same type – if not; it will return false.
Only if they are of the same type will it actually compare the two, the below function is in many ways equivalent of using
===.