Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Very illogical php value comparisons

Tags:

php

I stumbled upon a very strange bit of PHP code. Could someone explain why this is happening? *****BONUS POINTS***** if you can tell my why this is useful.

<?php
if(0=='a'){
    print ord(0)." should NEVER equal ".ord('a')."<br>";
}
if(false==0){
       print "false==0<br>";
}
if('a'==false){
       print "a==false<br>";
}
?>

And the resulting output:

48 should NEVER equal 97
false==0
like image 803
rook Avatar asked Jul 18 '10 04:07

rook


4 Answers

In PHP, 'a' is not the ASCII character a, but the string a. In a numeric context, it is equal to 0. For instance intval('a') results in a value of 0.

This is useful because PHP is primarily used for processing text, and one might want to try the test (123 == '123'), which is true. And given that a number in single (or double) quotation marks is treated as the number, it doesn't make sense for a string with no numeric value to be treated as anything other than 0.

Oh yeah, one more thing. 'a' in a boolean context is true, not false. I believe this makes some types of text processing more natural, but I honestly can't think of an example at this late hour.

like image 192
James McLeod Avatar answered Nov 19 '22 01:11

James McLeod


Well, there's always the PHP type cheat sheet for that!

like image 8
Jacob Relkin Avatar answered Nov 19 '22 03:11

Jacob Relkin


This is a basic principle of weakly/dynamically typed languages called type juggling. Types will be cast to other types in certain circumstances. When you compare a string to a number, the string will be cast into a number. When comparing anything to a boolean, that value will be cast to a boolean.

There are rules for every type as to how it will be cast into another type or how it compares to other types. 'a' happens to be converted to 0 when cast to a number (the only logical choice, really). To avoid this type casting, test not with the equality operator ==, but with the identity operator ===.

As James pointed out, this is useful since PHP deals a lot with strings that are really numbers. For example, HTML forms only submit strings, even if the value is a number. It also allows for some really terse code, like:

$result = someOperation();
if (!$result) {
    // $result may be null, false, 0, '' or array(),
    // all of which we're not interested in
    error();
}

It also means you have to be really careful about what to check for in which circumstances though, since a value might unexpectedly cast into something else. And admittedly, 'a' == 0 in itself is really a pitfall of type juggling rather than helpful. It's one of the situations where you have to be careful and test like if (is_numeric($var) && $var == 0).

like image 7
deceze Avatar answered Nov 19 '22 03:11

deceze


ord() takes characters, so PHP turns 0 into '0'. And 0 is equal to false, even though it is not identical (===).

like image 3
Ignacio Vazquez-Abrams Avatar answered Nov 19 '22 02:11

Ignacio Vazquez-Abrams