There are several ways to test that an array is empty in PHP, and the one I see most often is:
$var = [];
if (empty($var)) { ... }
By reading the code, you immediately know what it does, the name of the function is quite self-explanatory. But the problem is the use of the empty
function which is not only used to test array
!
Did you know that using empty
is like writing:
$var = [];
if (
isset($var) === false
|| $var === false
|| $var === 0
|| $var === -0
|| $var === 0.0
|| $var === -0.0
|| $var === ''
|| $var === '0'
|| $var === []
) { ... }
We can clearly see here that we can use empty
to also test that an integer is equal to 0
, or that a string is empty. And that's the problem with this function: it does too many things and can cause many bugs.
For example, a test with empty
of an undeclared variable returns true
without errors! So a bug can occur if you make a mistake in the name of your variable:
$var = [1, 2, 3];
var_dump(
empty($errorVar)
); // bool(true)
It is therefore better to test the expected value directly:
var_dump(
$errorVar === []
); // bool(false)
/*
* With php < 8 : Notice: Undefined variable: myErrorVar in /in/Nm3CT on line 8
* With php >= 8 : Warning: Undefined variable $myErrorVar in /in/Nm3CT on line 8
*/
What is the right method?
To test that an array
is empty, I advise you to use one of the suggestions below instead.
$var = [];
if (count($var) === 0) {...}
// ou
if (sizeof($var) === 0) {...}
My favorite solution:
$var = [];
if ($var === []) {...}
And more generally, I advise you to ban the empty
function from your vocabulary and your daily life:
- Want to test that an integer is equal to
0
?
$var === 0
- Want to test that a string is empty?
$var === ''
- Do you want to test that a previously declared and initialized variable is equal to
null
?
$var = null;
if ($var === null) {...}
- If you want to test that a variable exists and is different from
null
, you must use theisset
function
isset($var)
It's simple, isn't it?
What if I want to test several things at the same time?
If for example, you want to test that your variable is not null
and that it is not an empty string, you can either combine the two conditions:
if ($var !== null && $var !== '')
Either create a private
method with an explicit name which will do this control
private function isTokenValid(?string $token): bool
{
return $token !== null && $token !== '';
}
// in the condition
if ($this->isTokenValid($var)) {...}
Thank you for reading, and let's stay in touch !
If you liked this article, please share. Join me also on Twitter/X for more PHP tips.
Top comments (25)
why not:
You can.
It will force PHP to cast your variable in Boolean, which I want to avoid (for pretty the same reason to not use
empty
).And I find it more explicit.
I find it kind of explicit that an empty array "means" false
The problem is not that empty function returns false for an empty array, the problem is that empty function does to too many thing (not just on array).
Thanks for your comment !
The problem is "There are some instances where empty works well.". In some case, it works well, but sometimes it cause a bug and you search after the root cause.
A lot of PHP beginners don't know how it works exactly and will have bugs because of the versatility of this function.
Many senior developers that I know prohibit the
empty
function, for the reasons that I explained.It's just advice, then I'll let you do what you want ;)
A lot of PHP beginners don't know how works "if" or "for", so lets not use it...
I have an other article for these beginners, who don't know how to make a loop : dev.to/klnjmm/never-write-another-... ๐คฃ
I agree. I do not want to do 3 different validations since it is there and always has a scenario to fit
empty()
in my codebase (don't ask me why).I'd like to quote a famous singer who says important words regarding this statement:
What is just "3 different validations" in order to avoid bugs ?
just cast to bool
much more safe than empty & checks "", 0, null, false... etc. cases
This demonstrates a really good and safe way to use
empty
. In this case, we have a nullable string property. But, it could even be unset. In this case,getBar
should return the default value if$f->bar
is unset, null, or an empty string. This does exactly what it's supposed to do, and it's safe, because everything is typed. The only potential error here is the case of a typo, and that's what tools like phpstan (or your own IDE) are for.In case it wasn't obvious, the alternative would be:
You can't tell me that's better code.
It is a lot of combination that make the use of
empty
safe.For you second example,
isset
method test that the value is notnull
.So itโs just
Not so dirty ๐
I had forgotten that
isset
stupidly returns false for null values.Yes, not quite so bad, but I still prefer
empty
in this case.Ah yes, the annoying case where an explicit
null
value is different from an unset value. But if you have an object or array where you need to see if a property exists, this can be quite useful.For objects/classes where you don't need the distinction,
property_exists
is the function you want.This is one of those weird edge cases in dynamic programming languages. For the most part, I'll take the unset vs explicit null in PHP over the undefined/null split in Javascript.
Some months ago, I sent a proposal to php.dev for updating the empty function, because of internal flaws and semantic inconsistence. The new version I named is_empty_obj fixes all above.
Then roll your own!
When we talk about clean & readable code, we try to avoid large comparisons. So empty() function help us in that journey. I know itยดs not perfect because it canยดt eval objects in the same way, so if you donยดt want to be thinking when use it or not, instead eval two or three differents options, you can use your own Empty function, extending it in some core class or redefining with runkit7_function_redefine (I prefer first option).
Something like:
If you want to try:
empty function is FOR ME not ยซย clean codeย ยป. Itโs not a matter of comparing object, itโs because it tests too much thing and that can cause bugs.
Like I describe in the article, if you find your comparaison too ยซย bigย ยป, you can extract it in a method with a understandable name.
If you have to compare object, I think you can do it otherwise.
And for you, what is an ยซย emptyย ยป object ? A object with all attributes equal to null ?
I love the
empty
function!๐๐คฃ
I spent waaay too long trying to mirror the discussion.
I really hope this turns up in a technical interview someplace, somewhen.
I disagree. You should understand what you're doing and use the proper functions for each case. The
empty
isn't bad.As an argument: someone will copy your "right method"
if (count($var) === 0) {...}
as a "silver bullet" and apply it to an array with thousands of elements (because Jimmy said that's the solution). It will cause huge performance issues.Thanks for your reply.
Maybe Iโm wrong, but count on a large array is not slower than count on a small array. The size of an array is stored internally, PHP does not count the number of items each time you call the function.