Why does PHP consider 0 to be equal to a string?

前端 未结 9 1791
佛祖请我去吃肉
佛祖请我去吃肉 2020-11-22 02:41

I have the following piece of code:

$item[\'price\'] = 0;
/* Code to get item information goes in here */
if($item[\'price\'] == \'e\') {
    $item[\'price\'         


        
相关标签:
9条回答
  • 2020-11-22 03:16

    Your problem is the double equal operator, which will typecast the right member to the type of the left. Use strict if you prefer.

    if($item['price'] == 'e') {
        $item['price'] = -1;
    }
    

    Let's go back to your code (copied above). In this case, in most cases, $item['price'] is an integer (except when it is equal to e, obviously). As such, by laws of PHP, PHP will typecast "e" to integer, which yields int(0). (Don't believe me? <?php $i="e"; echo (int)$i; ?>).

    To easily get away from this, use the triple equal (exact comparison) operator, which will check the type and will not implicitly typecast.

    P.S: a PHP fun fact: a == b does not imply that b == a. Take your example and reverse it: if ("e" == $item['price']) will never actually be fulfilled provided that $item['price'] is always an integer.

    0 讨论(0)
  • 2020-11-22 03:17

    You are doing == which sorts out the types for you.

    0 is an int, so in this case it is going to cast 'e' to an int. Which is not parsable as one and will become 0. A string '0e' would become 0 and would match!

    Use ===

    0 讨论(0)
  • 2020-11-22 03:17
    "ABC" == 0
    

    evaluates true because first "ABC" is converted to integer and becomes 0 then it is compared to 0.

    This is an odd behaviour of the PHP language: normally one would expect 0 to be promoted to string "0" and then compared to "ABC" with a result false. Perhaps that's what happen in other languages like JavaScript where the weak comparison "ABC" == 0 evaluates false.

    Doing a strict comparison solves the problem:

    "ABC" === 0
    

    evaluates false.

    But what if I do need to compare numbers as strings with numbers?

    "123" === 123
    

    evaluates false because the left and right term are of different type.

    What is actually needed is a weak comparison without the pitfalls of PHP type juggling.

    The solution is to explicit promote the terms to string and then do a comparison (strict or weak doesn't matter anymore).

    (string)"123" === (string)123
    

    is

    true

    while

    (string)"123" === (string)0
    

    is

    false


    Applied to the original code:

    $item['price'] = 0;
    /*code to get item information goes in here*/
    if((string)$item['price'] == 'e') {
        $item['price'] = -1;
    }
    
    0 讨论(0)
提交回复
热议问题