Are 0=='' and '0'=='' same? - php

Consider the following PHP statements:
echo ( 0 == '' ? 1 : 0); // Output is 1
echo ('0' == '' ? 1 : 0); // Output is 0
The first will print 1, and the second will print 0. Shouldn't they both print 0? Is this expected behavior? I'm guessing its because the second is a string and the first is not, but I'd like another answer.

Read Loose comparisons with ==
http://php.net/manual/en/types.comparisons.php

In Php empty string, NULL and 0 are equal.
In second case '0' is another string, and '' is another. So you get result false.
"", 0, "0", False, array(), Null are all considered False in PHP.
You can use === to make them different.

It's correct behavior. 0 is equal to empty string as well as to false/null.

It is because the first line is not comparing two variables of the same type:
echo ( 0 == '' ? 1 : 0); // Output is 1
echo ('0' == '' ? 1 : 0); // Output is 0
Observe the following:
echo ( 0 === '' ? 1 : 0); // Output is 0
The === operator does a type sensitive equality check, which seems to be what you are expecting. == will do a bit of a fuzzy check if the two arguments are not of the same type.
You should check out the comparison operators documentation for more information:
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.

I think the first one is interpreting both the 0 and the empty string as "false" and they are coming out as equal. PHP has lots of quirks around what it will interpret as true/false.
The second is comparing the string '0' to a blank string and coming up with unequal.
To make sure you compare actual values you should use the === comparison

0 == '' == null
but '0' is a string.
You'd better use === to check the difference of 0, '0', null
php > var_dump(0);
int(0)
php > var_dump('0');
string(1) "0"
php > var_dump(null);
NULL
php > var_dump('');
string(0) ""

You can find the comparison logic here:
http://php.net/manual/en/language.operators.comparison.php
Type of Operand 1 Type of Operand 2 Result
null or string string Convert NULL to "", numerical or lexical comparison
string, resource string, resource Translate strings and resources to numbers, usual math
or number or number
That means for '0' == '', the first case applies, and lexical comparison is used. And "0" and "" are not equal according to lexical comparison.
For 0 == '', the second case applies. '' is converted to a number, 0 in this case, which is equal to 0.

'0' == '' will always be false. Because symbol '0' is not an empty symbol. But in PHP 0 (zero) and empty symbol are the same.

Related

String equal to "0" in PHP [duplicate]

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 item price to 0 and then get information about it. If the price is informed as 'e' it means an exchange instead of a sell, which is stored in a database as a negative number.
There is also the possibility to leave the price as 0, either because the item is a bonus or because the price will be set in a later moment.
But, whenever the price is not set, which leaves it with the initial value of 0, the if loop indicated above evaluates as true and the price is set to -1. That is, it considers 0 as equal to 'e'.
How can this be explained?
When the price is provided as 0 (after initialization), the behavior is erratic: sometimes the if evaluates as true, sometimes it evaluates as false.*
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 ===
From PHP.net:
Comparisons between strings and numbers using == and other non-strict
comparison operators currently work by casting the string to a number,
and subsequently performing a comparison on integers or floats. This
results in many surprising comparison results, the most notable of
which is that 0 == "foobar" returns true.
However this behavior was changed in PHP 8.0:
When comparing to a numeric string, PHP 8 uses a number comparison.
Otherwise, it converts the number to a string and uses a string
comparison.
PHP 7
0 == 'foobar' // true
0 == '' // true
4 == '4e' // true (4e is cast as a number and becomes 4)
PHP 8 converts numbers to strings before making comparisons
0 == 'foobar' // false
0 == '' // false
4 == '4e' // false ('4e' is considered non-numeric therefore 4 is cast as a string and becomes '4')
This is a major change therefore it was implemented in a new major PHP version. This change breaks backward compatibility in scripts that depend on the old behavior.
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.
"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;
}
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
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.
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
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"
Basically, always use the === operator, to guarantee type safety.
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)

PHP compare equality, empty string, "0" and 0

I learned that the empty string "", 0 and "0" all mean false in php. I wonder does php take that into account when it comes to comparing equality.
$str = "";
echo ($str == "0") ? "yes" : "no"; // prints "no" (A)
echo ($str == 0) ? "yes" : "no"; // prints "yes" (B)
Line A suggests that php is comparing $str and "0" as if they are all strings, ignoring that they both can mean false. But line B is comparing their "false" interpretation.
So is it the case that php firstly checks if the two values have the same type, if so it checks equality assuming the same type; if not, it uses the boolean meanings of the values (is there type casting involved?)
I learned that the empty string "", 0 and "0" all mean false in php.
This statement is false. Empty string, 0 and "0" are false when casted to boolean type. Otherwise they are either empty string, integer zero or string with one character, respectively.
== checks values of two variables. If their types are different, some casting happens and unpredictable (for rookies) results come up.
=== checks values of two variables and their types.
Anyway, when you compare "0" == "", PHP interpreter compares two strings which are different. But when you go with 0 == "" it first changes numeric string to integer. Empty string equals 0. So we end up with 0 == 0 which is true.
Note: "8abc" becomes 8 after casting to integer. abc8 becomes 0 when casted
Manual on:
- Types casting (juggling)
- Types comparison
There are two equality comparator in PHP
When the types are the same, they behave in the same way.
When the types are different, it all depends: PHP does not cast both values to booleans. It depends on the types of both operands, and there is a table to know what PHP will do (see second link).
I recommend reading this stackoverflow question
How do the PHP equality (== double equals) and identity (=== triple equals) comparison operators differ?
Also, the PHP manual for comparison
http://au.php.net/manual/en/language.operators.comparison.php
// double equal will cast the values as needed followin quite complex rules
0 == '0' // true, because PHP casted both sides to numbers
// triple equals returns true only when type and value match
0 === '0' // false
$str = "";
//Comparing two strings, no implicit type conversion happens. Since
// "" is not equal "0", result is FALSE
echo ($str == "0") ? "yes" : "no"; // prints "no" (A)
//Comparing a STRING to an INT,implicit conversion happens to convert
// the string "" to an INT. Since "" has no digits, it's evaluated
// to 0. Hence, result of comparison is TRUE
echo ($str == 0) ? "yes" : "no"; // prints "yes" (B)
Use "===" for more accurate comparison.

PHP: If statement issue

The array resAlloc contains 10 columns and 5 rows. All entries are equal to 0. So, I expect the following IF statement be TRUE, but it's false for some reason... Why?
if ($resAlloc[$i][$j] != 'ts' && $resAlloc[$i][$j] != 't' && $resAlloc[$i][$j] != 'st') {
$count++;
}
!= evaluates 0 as false. Use !== which is more strict.
IIRC anything equaling 0 with != will return FALSE.
The problem is that you're comparing a string and an integer, and PHP is "helpfully" casting the string to an integer -- the integer zero. 0!='ts' evaluates as false, because the comparison it ends up doing after conversion is 0!=0. You can prevent this by explicitly treating the contents of your array as a string:
strval($resAlloc[$i][$j]) != 'ts'
This will do the comparison '0'!='ts', which correctly evaluates to true. If you pass strval() a string it returns it unchanged, so this should be safe to use regardless of what's in your array.
Alternately, as Samy Dindane said, you can just use !== which won't do any type conversion.

php operator == (sort of equality) and the integer 0

php, my dearest old frienemy.
ok, so i can come to terms with why the string '0' would be a falsie value. that's only fair seeing as how '0' is the same as 0 in a loosely typed language, and 0 is false in a loosely typed language. so this gives that false == 0 == '0'.
fine fine... BUT!! what is this all about?
<?php
print "number of surprised persons: " . ('false' == 0);
the output is....
number of surprised persons: 1
how is this reasonable? am i the only one who's surprised by this? what am i failing to see?
further testing has proven that the integer 0 is equal (by operator ==) to
0 <-- integer
false <-- boolean
null <-- just.. you know, null
'0' <-- string
'' <-- string
'false' <-- string
'true' <-- string
'null' <-- string
naturally, i mostly use operator === to compare stuff. and now that i know about this, i'll have to adjust my programming of course, no question about that. but still! can someone shed some light pl0x?
It's because, when you compare a string to an integer, they don't both get converted to strings, or to booleans - they get converted to integers. For PHP, when you think about it, this isn't strange at all (comparatively, I suppose).
'true' == 0
// is the same as
(int)'true' == 0
// is the same as
0 == 0
// is the same as
true
And this is true for any non-numeric string as well as the string "0". The reason 1 is printed out is because the string version of true is 1 (and the string version of false is an empty string).
As far as you're concerned about the output:
('false' == 0) = boolean TRUE = string "1".
echo is triggering string context.
But from your comment below I've just seen, that you'd like to learn more about the comparison. Take a look what you do:
Example Name Result
$a == $b Equal TRUE if $a is equal to $b after type juggling.
so you are doing a non-strict comparison of a number with a string:
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. (REF)
Note: Number, not integer as written in the accepted answer:
<?php
print "number of surprised persons: " . ('false' == 0.3 - 0.2 - 0.1);
Have fun.
false == 0 is true. True as a string is '1' and you are doing an implicit conversion when you interpolate the value.
$a = true;
echo "$a"; #1
You can find a PHP truth table here. I would just recommend the === comparator unless you have a good reason to use ==
http://php.net/manual/en/types.comparisons.php

Why the value being equalled to string in php

It is in this way:
$arr_val = array(0,1,'0','1');
foreach ($arr_val as $key){
echo ($key == "TEST")?"EQUALLED":"NOT EQUALLED"."<br>";
}
0 == "TEST" prints "EQUALLED"
1 == "TEST" prints "NOT EQUALLED"
'0' =="TEST" prints "NOT EQUALLED"
'1' =="TEST" prints "NOT EQUALLED"
When I say it prints the value "SELECTED". But why the above first case prints equalled. Any ideas on this please? How would this be equal to. We know the fix to do comparision with
(===) operator. But I am trying to know the reason why (0=="TEST") is true.
When you provide PHP's == operator with a mixture of numeric and string operands, PHP will attempt to convert the string to the matching numeric type, part of a process it calls "type juggling". In this case, the string "TEST" converts to integer 0 so your test is equivalent to 0 == 0 which is true.
PHP provides the === operator, for testing if the value and type of both operands are equal. So while 0 == "TEST" will evaulate to true, 0 === "TEST" will not, and neither will 0 === "0" or 0 === 0.0.
Note that when PHP converts a string to a number, it attempts to parse the string for a valid number. See intval for more information on how it does this. Had you'd written 0 == "1TEST", the expression would have evaulated to 0 == 1, or false.
In your second example, 1 == "TEST", the string "TEST" is again converted to an integer resulting in 1 == 0, which is false.
Your last two examples use string comparisons. There is no conversion involved, and the results are self-explanatory.
PHP provides a comprehensive breakdown of how variables of different type compare for equality.
Because 0 is an integer, behind the scenes, this is the comparison that happens:
0 == intval( "TEST" )

Categories