Why does PHP consider 0 equal to a string?

I have the following piece of code:

$item['price'] = 0; /*code to get item information goes in here*/ if($item['price'] == 'e') { $item['price'] = -1; } 

It is intended to initialize the price of goods to 0, and then to obtain information about it. If the price is indicated as "e", this means an exchange instead of a sale, which is stored in the database as a negative number.

It is also possible to leave the price as 0, because the product is a bonus or because the price will be set later.

But whenever the price is not set, which leaves it with an initial value of 0, the above if loop is evaluated as true, and the price is set to -1. That is, he considers 0 equal to "e".

How can this be explained?

Edit: when the price is specified as 0 (after initialization), the behavior is erroneous: sometimes if evaluates to true, sometimes as false.

+95
string php numbers
Jul 27 '11 at 10:45
source share
8 answers

you do == which sorts the types for you.

0 is an int, so in this case it will distinguish 'e' from int. Which cannot be parsed as one and becomes 0 . The string '0e' will become 0 and will match!

use ===

+94
Jul 27 2018-11-11T00:
source share

This is due to how PHP performs the comparison operation, which the comparison operator == means:

If you are comparing a number with a string or the comparison includes numeric strings, each string is converted to a number and the comparison is performed numerically. [...] Type conversion does not occur when comparison === or !== , since this includes a comparison of the type as well as the value.

Since the first operand is the number ( 0 ) and the second is the string ( 'e' ), the string is also converted to a number (see also the table Comparison with various types ). The manual page in a string data type determines how a string is executed to convert numbers :

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

If the string does not contain the characters " . ", " e " or " e ", and the numeric value matches the restrictions of the integer type type (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 therefore will be evaluated as a float:

The value is specified by the start 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 metric. A metric is an e or e followed by one or more digits.

Since 'e' does not start with valid numeric data, it computes float 0 .

+45
Dec 29 '11 at 19:22
source share
 "ABC" == 0 

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

This is a strange behavior of the PHP language: you can usually expect 0 be cast to the string "0" and then compared to "ABC" with the result false . Perhaps what happens in other languages, such as JavaScript, where a weak comparison "ABC" == 0 evaluates to false .

A rigorous comparison solves the problem:

 "ABC" === 0 

evaluates false

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

 "123" === 123 

evaluates to false because the left and right members are of different types.

What is really needed is a weak comparison without traps in PHP juggling.

The solution is to explicitly push the terms into the string and then compare (strong or weak no longer matters).

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

is an

true

while

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

is an

false




Applied to the source code:

 $item['price'] = 0; /*code to get item information goes in here*/ if((string)$item['price'] == 'e') { $item['price'] = -1; } 
+13
Feb 21 '18 at 17:59
source share

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

 '0' == 0 will be true 

If you need type comparisons, use the === operator:

 '0' === 0 will be false 
+8
Jul 27 2018-11-11T00:
source share

Your problem is the double equality operator, which will assign the right member to the type on the left. Use strict if you want.

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

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). Thus, according to the laws of PHP, PHP will output "e" to integer, which gives int(0) . (Do not believe me? <?php $i="e"; echo (int)$i; ?> ).

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

PS: fact of fun PHP: a == b does not mean that b == a . Take your example and discard it: if ("e" == $item['price']) will never execute provided that $ item ['price'] is always an integer.

+8
Mar 29 '13 at 14:47
source share

In PHP there is a rather convenient method for checking the combination of "0", "false", "off" as == false and "1", "on", "true" as == true, which is often ignored. This is especially useful for parsing. GET / POST arguments:

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

This does not apply to this use case, but given the similarities and the fact, this is the result of a search that it tries to find when it asks a question about checking (string) "0" as false. I thought this would help others.

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

+6
Apr 26 2018-12-12T00:
source share

You should use === instead of == because the regular operator does not compare types. Instead, he will try to style the goods.

Meanwhile === takes into account the type of items.

  • === means equal,
  • == means "eeeeh .. kinda looks like"
+5
Jul 27 2018-11-11T00:
source share

I think it’s best to show the examples that I did, while at the same time faced with the same strange behavior. See my test case, and hopefully it helps you better understand the behavior:

 //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). 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 why its true) echo ("bla" === "blaa"); //false because the values are not the same. The type is the same but === check 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 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) //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) 

Hope it helps.

+1
Feb 15 '19 at 11:31
source share



All Articles