PHP + JavaScript:将空字符串与0进行比较时,幕后会发生什么

Because of loose typing, PHP has to cast both compared variables to the same type, if they aren't yet. What happens behind the scenes for this comparison:

$v = "" == 0;

It returns true. If the type of the first variable is internally casted to the type of the second variable, I can understand it:

$v = (int)"" === 0;

But if it were so, the inverse comparison should fail:

$w = 0 == "";

because

(string)0 = "0"

which is obviously not equal to "".

but it returns true, as well.

The same behavior can be observed with JavaScript.

So now I am asking myself: what happens there?! The only explanation for me is that both variables are casted to boolean. But in this case, ["X"] == "X" should return true, but it obviously doesn't. So, what's the magic to assume "" equal 0?

In PHP when using the equal it will convert the input so that the following are all equal:

0 == "" == false

Which all will pass an empty() check.

If you want to check the exact type use === instead. To answer your comment, array() is not a variable, but rather a data structure, that is why it fails the == check but passes the empty() check.

In JavaScript, the behavior of == is defined in The Abstract Equality Comparison Algorithm.

  • When you do "" == +0, since Type("") is String and Type(+0) is Number, the returned value is the result of the comparison ToNumber("") == +0.

    The behaviour of applying ToNumber to String type is defined in ToNumber Applied to the String Type. In our case, ToNumber("") returns +0.

    Now we must check +0 == +0. Since both have the same Type, that Type is Number, and both +0 and +0 have the same Number value, the returned value is true.

  • When you do +0 == "", since Type(+0) is Number and Type("") is String, the returned value is the result of the comparison +0 == ToNumber("").

    The behaviour of applying ToNumber to String type is defined in ToNumber Applied to the String Type. In our case, ToNumber("") returns +0.

    Now we must check +0 == +0. Since both have the same Type, that Type is Number, and both +0 and +0 have the same Number value, the returned value is true.

php favors integers in comparisons, so if either value is an int the comparison will be done as an int.

The "int-ness" is determined not by type, but by an is_numeric() test. Strings are silently converted to numbers even when you don't expect it, so "1.2" == "1.20" is true (!?). Some versions of php used to say two long numeric strings were equal if they had an int overflow with idential prefixes.

Javascript seems to also cast to number when comparing to a number, but two strings compare as strings.