Please note that results of empty() when called on non-existing / non-public variables of a class are a bit confusing if using magic method __get (as previously mentioned by nahpeps at gmx dot de). Consider this example:

The result for empty($registry->notEmpty) is a bit unexpeced as the value is obviously set and non-empty. This is due to the fact that the empty() function uses __isset() magic functin in these cases. Although it's noted in the documentation above, I think it's worth mentioning in more detail as the behaviour is not straightforward. In order to achieve desired (expexted?) results, you need to add __isset() magic function to your class:

I'm summarising a few points on empty() with inaccessible properties, in the hope of saving others a bit of time. Using PHP 5.3.2.<?phpclass MyClass { private $foo = 'foo';}$myClass = new MyClass;echo $myClass->foo;?>As expected, this gives "Fatal error: Cannot access private property MyClass::$foo".But substitute the lineif (empty($myClass->foo)) echo 'foo is empty'; else echo 'foo is not empty';and we get the misleading result "foo is empty". There is NO ERROR OR WARNING, so this is a real gotcha. Your code will just go wrong silently, and I would say it amounts to a bug.If you add two magic functions to the class:public function __get($var) { return $this->$var; }public function __isset($var) { return isset($this->$var); }then we get the expected result. You need both functions.For empty($myClass->foo), I believe PHP calls __isset, and if that is true returns the result of empty on the result of __get. (Some earlier posts wrongly suggest PHP just returns the negation of __isset).BUT …See the earlier post by php at lanar dot com. I confirm those results, and if you extend the test with isset($x->a->b->c) it appears that __isset is only called for the last property in the chain. Arguably another bug. empty() behaves in the same way. So things are not as clear as we might hope.See also the note on empty() athttp://uk3.php.net/manual/en/language.oop5.overloading.phpClear as mud!

This is correct, per the documentation (http://php.net/manual/en/language.types.string.php); quite a bit down the page is the Warning: "Writing to an out of range offset pads the string with spaces. Non-integer types are converted to integer." ) I didn't receive a warning but perhaps that's correct too...depends on whether the string -> integer conversion is considered "illegal": "Illegal offset type emits E_NOTICE."

(i.e. since $params['search'] is a string, the 'filter' subscript is converted to 0, so the test becomes empty($params['search'][0]), which is obviously false), but it tripped me up enough to mistakenly file a bug report (which I've since closed).

Using str_replace is unnecessary. I would encourage the use of trim which would most likely be faster (haven't tested) and easier. Trim also takes care of other white space like line breaks and tabs. Actually, in most of the applications I code, I use a multi-dimensional array map function with trim on the Super Globals such as $_POST, $_GET and $_COOKIE as so far, there hasn't been an instance where I would want any user input to begin or end with whitespace. The good thing about doing this is that you never have to worry about 'trimming' your input which makes your code easier and more reliable (incase you forget to trim some input).

To add on to what anon said, what's happening in john_jian's example seems unusual because we don't see the implicit typecasting going on behind the scenes. What's really happening is:

$a = '';$b = 0;$c = '0';

(int)$a == $b -> true, because any string that's not a number gets converted to 0$b==(int)$c -> true, because the int in the string gets convertedand$a==$c -> false, because they're being compared as strings, rather than integers. (int)$a==(int)$c should return true, however.

Note: I don't remember if PHP even *has* typecasting, much less if this is the correct syntax. I'm just using something for the sake of examples.

I can't use empty() in all situations because '0' is usually not considered empty to me. I did a quick benchmark over the most common ways of testing it. '' == var suffers from '' == 0 is true so that's just there for curiosity.

Calling non existing object property, empty($object->prop), will trigger __isset(), the same way as isset($object->prop) does, but there is one difference. If __isset() returns TRUE, another call to __get() will be made and actual return value will be result of empty() and result of __get().

Be careful, if "0" (zero as a string), 0 (zero as an integer) and -0 (minus zero as an integer) return true, "-0" (minus zero as a string (yes, I already had some customers that wrote -0 into a form field)) returns false. You need to cast your variable before testing it with the empty() function :

empty() should not necessarily return the negation of the __isset() magic function result, if you set a data member to 0, isset() should return true and empty should also return true. A simpler implementation of the __isset magic function would be:

public function __isset($key) { return isset($this->{$key});}

I don't understand why this isn't included in stdClass and inherited by default.

When using the php empty() function to check submitted variables such as $_POST or $_GET, be careful to remember that values 0 (integer) and "0" (string with zero character) are all considered empty. eg. in a simple cms a page ID of zero might be used to indicate that the homepage should be displayed but using the following code:

For those of you using MySQL, if you have a table with a column of decimal type, when you do a SELECT, your data will be returned as a string, so you'll need to do apply intval() before testing for empty.

While that may be true, those two statements (empty($var), $var == '') are NOT the same. When programming for web interfaces, where a user may be submitting '0' as a valid field value, you should not be using empty().

David from CodeXplorer:>> The ONLY reason to use empty() is for code readability. It is the same as an IF/ELSE check.>> So, don't bother using EMPTY in the real world.

This is NOT true. empty() will not generate warnings if you're testing against an undefined variable as a simple boolean check will. On production systems, warnings are usually shut off, but they are often active on development systems.

You could test a flag with<?php if ($flagvar) ... ?>but this can generate a warning if $flagvar is not set.

The closest the documentation comes to saying this is:"var $var; (a variable declared, but without a value in a class)"which isn't really the same, as the variable doesn't necessarily have to be declared first.

Since a few people here mentioned that empty will not work with magic-overloading ("__get($var)"):

empty(..) goes the same way as isset(..) do, to check if a property exists. Thus you have to override the magic-function __isset($var) to produce correct results for empty(..) in combination with a magic-overloaded property.

There's a faster and easier to write method than (isset($a) && strlen($a)) -- isset($a{0}). It evaluates to false if $a is not set or if it has zero length (ie. it's first character is not set). My tests indicate that it's about 33% faster.

Mad Hampster did his test wrong. empty is NOT faster than a simple boolean check. The ONLY reason to use empty() is for code readability. It is the same as an IF/ELSE check. But if you are dealing with intermediate or higher level coders this function has no other benefit.

So, don't bother using EMPTY in the real world.

I ran an array with 5000 simple true/false values through four checks (both types twice) in case of any gain one type might have by going first. These are my results generated one one page request. (PHP5)

0.015328 Time EMPTY0.014281 Time IF/ELSE0.015239 Time EMPTY0.013404 Time IF/ELSE