views:

134

answers:

6

PHP:

$a = "0";
$b = "00";
var_dump(empty($a)); # True (wtf?)
var_dump($a == $b); # True... WTF???
var_dump(empty($b)); # False WWWTTTFFFF!!??

I've read the docs. But the docs don't give explanation as to why they designed it this way. I'm not looking for workarounds (I already know them), I'm looking for an explanation.

Why is it like this? Does this make certain things easier somehow?

+2  A: 

http://au2.php.net/empty

The following things are considered to be empty: "0" (0 as a string)

but "00" will not be considered empty.

DmitryK
as for n2 one - try strict comparision === instead of the loose one ==
DmitryK
was meant to be "as for the second one - try..."
DmitryK
A: 

Check the docs for empty http://us.php.net/empty. That should take care of the first and third lines.

for the second, it's because PHP is dynamically typed. the interpreter is inferring the type of the variables for use in the context in which you have used them. In this case the interpreter is probably thinking that you are trying to compare numbers and converting the string to ints before comparing.

Ariel
A: 

From the documentation one can assume that 0 can be either an int or a 1 char string to signify empty. 00 would be more of a formatting assumption since there's no such thing as 00, but there is 0. 00 would be implying a 2 integer format, but the empty() function is only written for 0.

FWIW IANA php developer.

bobby
+1  A: 

It has do do with what PHP considers empty, and, as @Shadow imagined, it's a dynamic typing issue. 0 and 00 are equal in PHP's eyes. Consider using the strict equality instead:

($a === $b) // is a equal to b AND the same type (strings)

Typeoneerror
+9  A: 

As for "0" == "00" resolving to true, the answer lies in Comparison Operators:

If you compare an integer with a string, the string is converted to a number. If you compare two numerical strings, they are compared as integers. These rules also apply to the switch statement.

(emphasis added)

Both "0" and "00" are numerical strings so a numerical comparison is performed and obviously 0 == 0.

I'd suggest using === instead if you don't want any implicit type conversion.

As for empty():

The following things are considered to be empty:

  • "" (an empty string)
  • 0 (0 as an integer)
  • "0" (0 as a string)
  • NULL
  • FALSE
  • array() (an empty array)
  • var $var; (a variable declared, but without a value in a class)
cletus
+1  A: 

It all stems from the language designers goal of "doing the right thing".

That is a given piece of code should do what the niave programmer or casual viewer of a piece of code would expect it too. This was not an easy goal to acheive.

Php has avoided most of worst pitfalls of other languages (like C's if (a = b) { ... or perl' s if ( "xxxx" == 0) { print "True!"; }). The 0 == 0000 and if ("000") { echo "True!"; } are two of the few cases where code might not do exactly what you expect, but in pracice it is seldom a problem. In my experience the "cure" using the exact comparison operator === is the one thing guarenteed to have novice php programmers scratching there heads and searching the manual.

James Anderson
So far you're the only one who actually addressed what I was asking.
Fragsworth