Be Careful Using PHP's empty()

published:
2009.02.09
topics:
php

Glen Stansberry recently shared his great tutorial about 10 PHP Mistakes, but I thought there was one other mistake so important and easy to make that it was worth explaining: PHP programmers of all skill levels can easily use the empty() language construct incorrectly.

1. Do Use empty() with Arrays

PHP's empty() is very useful for dealing with PHP arrays since it returns true if your array variable is null or an empty array, and also gracefully returns true if your array variable is undefined.

if (!empty($myarray)) {
    // this code runs if $myarray is defined, not null, and not an empty array()
}

2. Do Not Use empty() with Strings

In many cases, empty() cannot be used with string variables for the simple fact that empty() returns true if your variable is set the the string value '0'. If the string character '0' is a possibly valid value for your string variable — if all non-zero-length strings are valid — you cannot use empty(). This is even more dangerous if you are using empty() to check if a string variable is defined. Also worth mentioning, empty() returns false for a string value that is nothing but a single space (or any number of spaces really).

$mystring = '0';
if (empty($mystring)) {
    // this code will run
    // what if this was code to take action when $mystring is undefined?
}

$mystring = ' ';
if (empty($mystring)) {
    // this code will NOT run
}

However, you cannot simply replace the use of empty() with a conditional that checks if the string variable is equal to null or has a string length of zero. If your string variable happens to be undefined, empty() will quietly return true whereas strlen($mystring) and $mystring == null will throw PHP warnings. If your variable may possibly be undefined, then you have to first check of the variable is defined using isset(). After that you can check if the string is null.

// $mystring is NOT defined
//$mystring = null;
if (empty($mystring)) {
    // the condition passes without a warning
}

if ($mystring == null) {
    // the condition passes WITH a warning
}

if (!isset($mystring) || $mystring == null) {
    // the condition passes without a warning
    //
    // this conditional is a suitable replacement for empty() when
    // dealing with strings
}

Why does empty() return true for the string value '0'? Well, because PHP is a loosely typed language, and empty() returns true for the integer value 0. If somehow the string value of '0' ended up in a variable you are using as an integer, you would actually want the string '0' treated the same as as the integer 0. Stuff like this is actually why people argue for stronger typing.

3. PHP4 and PHP5 Differences with empty() and Objects

The PHP documentation for empty() states: "As of PHP 5, objects with no properties are no longer considered empty."

class Foo {
    function Foo() {
    }
    
    function bar() {
    }
}

$foo = new Foo();

if (empty($foo)) {
    // this code executes in PHP4 (but NOT in PHP5)!
}

4. Writing Your Own empty()? Not So Fast!

I know some of you reading this were all set to write your own wrapper for empty(). Maybe you were going to call it is_empty(), and it was going to cleverly address all of the information above? One major problem: don't forget that empty() is not a function, it is a PHP language construct. It shares a unique behavior with PHP's isset() in that it will not throw a PHP warning if you call it with a variable that is undefined. If you call your is_empty() with an undefined variable you will be generating a PHP warning that may end up being displayed to your end users or may slow your page down by triggering PHP error logging.