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

前端 未结 9 1790
佛祖请我去吃肉
佛祖请我去吃肉 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 02:53

    You should use === instead of ==, because the ordinary operator does not compare the types. Instead it will attempt to typecast the items.

    Meanwhile the === takes in consideration type of items.

    • === means "equals",
    • == means "eeeeh .. kinda looks like"
    0 讨论(0)
  • 2020-11-22 02:57

    This is due to how PHP does the comparison operation that the == comparison operator denotes:

    If you compare a number with a string or the comparison involves numerical strings, then each string is converted to a number and the comparison performed numerically. […] The type conversion does not take place when the comparison is === or !== as this involves comparing the type as well as the value.

    As the first operand is a number (0) and the second is a string ('e'), the string is also converted to a number (see also table Comparison with Various Types). The manual page on the string data type defined how the string to number conversion is done:

    When a string is evaluated in a numeric context, the resulting value and type are determined as follows.

    If the string does not contain any of the characters '.', 'e', or 'E' and the numeric value fits into integer type limits (as defined by PHP_INT_MAX), the string will be evaluated as an integer. In all other cases it will be evaluated as a float.

    In this case the string is 'e' and thus it will be evaluated as a float:

    The value is given by the initial portion of the string. If the string starts with valid numeric data, this will be the value used. Otherwise, the value will be 0 (zero). Valid numeric data is an optional sign, followed by one or more digits (optionally containing a decimal point), followed by an optional exponent. The exponent is an 'e' or 'E' followed by one or more digits.

    As 'e' does not start with a valid numeric data, it evaluates to float 0.

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

    I think it is best to show by examples I did, while running into the same weird behavior. See my test case and hopefully it will help you understand the behavior better:

    // Normal comparison using the == Operator
    echo (0 == "0"); // true
    echo (0 == "a"); // true
    echo (0 == "safta!"); // true
    echo (1000 == "bla"); // false. It appears that PHP has a weird behavior only with the number / string 0 / "0" according to the past 3 examples.
    echo (23 == "23"); // true. So as we said, PHP has a problem (not a problem but weird behavior) only when the number / string 0 (or "0") is present
    echo (23 == "24"); // false. values aren't equal (unlike last example). The type is less relevant with the == operator as we can see.
    
    // Now using the === and !== Operators
    echo ("0" === 0); // false, since === requires both value and type to be the same. Here, type is different (int vs string)
    echo ("0" !== 0); // true because they aren't the same in terms of === comparison (type is different and that's why it's true)
    echo ("bla" === "blaa"); // false because the values are not the same. The type is the same, but === checks for both equal type and equal value.
    
    //Now using casting and === Operator:
    echo ((string)123 === "123"); // true. The casting of the int 123 to string changed it to "123" and now both variables have same value and are of same type
    echo ((int)"123" === 123); // true. The casting of the string 123 to int, changed it to int, and now both variables are of same value and type (which is exactly what the === operator is looking for)
    
    // Now using casting and == Operator. Basically, as we've seen above, the == care less for the
    // type of var, but more to the value. So the casting is less relevant here, because even
    // without casting, like we saw earlier, we can still compare string to int with the == operator
    // and if their value is same, we'll get true. Either way, we will show that:
    echo ((string)123 == "123"); // true. The casting of the int 123 to string changed it to "123" and now both vars have same value and are of same type
    echo ((int)"123" == 123); // true. The casting of the string 123 to int, changed it to int, and now both vars are of same value and type (which is exactly what the === operator is looking for)
    
    0 讨论(0)
  • 2020-11-22 03:11

    The == operator will try to match values even if they are of different types. For instance:

    '0' == 0 will be true
    

    If you need type comparison as well, use the === operator:

    '0' === 0 will be false
    
    0 讨论(0)
  • 2020-11-22 03:12

    Basically, always use the === operator, to guarantee type safety.

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

    There's a rather handy method in PHP for validating a mix of "0", "false", "off" as == false and "1", "on", "true" as == true which is often overlooked. It's particularly useful for parsing GET/POST arguments:

    filter_var( $item['price'], FILTER_VALIDATE_BOOLEAN );
    

    It's not wholy relevant to this use-case but given the similarity and fact this is the result search tends to find when asking the question of validating (string)"0" as false I thought it would help others.

    http://www.php.net/manual/en/filter.filters.validate.php

    0 讨论(0)
提交回复
热议问题