This sort of thing happens in type conversion languages. You can either use === to stop conversion or you can understand how conversion works.
I'm not sure how the order of conversions is decided by PHP, but here's a brief explanation:
Compare "foo" to true. Convert the string "foo" to a boolean value. As it is desirable that a non-empty string evaluate to true, we will say they are "equal."
Compare "foo" to 0. Convert the string "foo" to a numeric value. As "foo" does not start with 0x it cannot be hex, and as it does not start with 0 it cannot be octal, so evaluate it as decimal - there are no numbers before the first letter so the string foo, when numerical, is 0.
Evaluate 0 to false. Well, that's just binary now isn't it? Of course false and 0 are equal!
The moral of the story, == is not "exactly equal" it is "relatively equal."