Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How come ('-' == 0) === true?

I was working here with some exploded string walks:

array_walk($data, function(&$value)
{
    // Transform numerics into appropriate type numbers
    if (is_numeric($value))
    {
        $value = substr_count($value, '.') == 1 ? (float) $value : (int) $value;
    }

    // Transform dashes into nulls
    if ($value == '-')
    {
        $value = null;
    }
});

to transform values into their appropriate types, and some special character handling.

Where I stumbled upon an interesting, huh, bug?

The Bug

I was amazed, that each entry, that had it's initial value as string(1) '0' ended up being a null.

At first, I thought that the problem relies in (float) and (int) typecasts, though, after debugging:

var_dump((float) '0', (int) '0');

I saw that's not the case, getting the expected result:

float(0)
int(0)

It took me a while, to attempt to debug the, what at the moment appeared to be an obvious, weak type check, but, once I did, I was shocked:

var_dump('-' == 0);

The above expression appears to be:

bool(true)

Now, while writing, I thought I should debug some more, so:

var_dump( '=' == 0 );
var_dump( 'What a lovely nonsense?' == 0 );
var_dump( 0 == 'DAFUQ?' ); // maybe it's because of order? It's PHP, world of miracles, you know...

And, every expression listed above is bool(true).

Okay, maybe that's because internally, mystically PHP casts the expression into a (bool)?

var_dump( (bool) '-' == 0 );

No:

bool(false)

So, so, so...

I made a test-case here: http://codepad.org/smiEvsDj
The problem exists in 5.2.5 (codepad), also in 5.4.3 (friend) and also in 5.4.17 (my actual environment).

What is the reason behind this feature / bug / what-the-F-actually-is-this?

like image 811
tomsseisums Avatar asked Aug 16 '13 09:08

tomsseisums


People also ask

Why is false == 0 is true in JS?

In JavaScript “0” is equal to false because “0” is of type string but when it tested for equality the automatic type conversion of JavaScript comes into effect and converts the “0” to its numeric value which is 0 and as we know 0 represents false value. So, “0” equals to false.

Why would you use === instead of ==?

== Operator: This operator is used to check the given values are equal or not. If yes, it returns true, otherwise it returns false. === Operator: This operator is used to check the given values and its data type are equal or not. If yes, then it returns true, otherwise it returns false.

Does the integer 0 == false?

When converting to bool, the following values are considered false : the boolean false itself. the integer 0 (zero) the floats 0.0 and -0.0 (zero)

Does 0 equal false or true?

Zero is used to represent false, and One is used to represent true. For interpretation, Zero is interpreted as false and anything non-zero is interpreted as true. To make life easier, C Programmers typically define the terms "true" and "false" to have values 1 and 0 respectively.


1 Answers

You have stumbled upon one of the major complaints that people have about PHP as a language: The fact that the "==" operator is not transitive.

Any string "foo" == TRUE, because the PHP people wanted this to work:

if ($string) {
    // do something if $string is set
}

Yet, converting a string to a number (which PHP always tries to do when you use "=="), "foo" == 0!

Of course, TRUE != 0. That is a major pain when dealing with PHP, it's not logical, but it's reality.

like image 183
ciruvan Avatar answered Oct 02 '22 16:10

ciruvan