Article

When to use empty in PHP? I'd say never

I realized that I am very strict about the use of PHPs empty function in code review. There isn't really any reason to use it in my opinion:

  • it tests both for the existance and the non-falsy value and as a reader the writers intent is not clear.
  • it does not communicate what type a variable has, seeing empty($value) does not narrow down what value is enough.
  • it hides errors caused by typos in the variable name passed to empty.

This is a list of alternatives that I recommend to use instead of empty.

// Replace
if (empty($string)) {
}

// With
if (strlen($string) === 0) {
}

Using strlen communicates that the variable is a string.

// Replace
if (empty($array)) {
}

// With
if (count($array) === 0) {
}

Using count communicates that the variable is an array.

// Replace
if (empty($array[$key])) {
}

// With
if (array_key_exists($array, $key)) {
}

// or if you know that existance also means a non-empty value
if (isset($array[$key])) {
}

Both array_key_exists and isset more clearly communicate that the code cares about the existance of a key and not that it assumes existance and tests only for a non-empty value.

// Replace
if (empty($var)) {
}

// With
if (isset($var)) {
}

In this case you can also use isset, but in general if you need to check this there is something wrong with the code anyways. A variable should always be or not be declared in the current scope, there should not be uncertainty about it.

// Replace
if (empty($var)) {
}

// With
if ($var === null) {
}

Code is more cleary a test for the variable being null and not accidently also true when 0, false or empty string.

// Replace
if (empty($var)) {
}

// With
if ($var === 0) {
}

Communicates that variable is integer.

// Replace
if (empty($var)) {
}

// With
if ($var === false) {
}
if (!$var) {
}

Communicates that variable is boolean.

Now what if I want to test for existance and non emptiness for an array keys? Using two conditions makes this more clear.

Now what if I care about performance of empty being a language construct vs calling an internal function such as strlen or count? No worries, both strlen and count are optimized by Opcache if you prefix them with a backslash to directly call them in the global namespace.

Armed with PHP Code Sniffer and Psalm I am happy to enforce rules with my own custom plugins for either one tool.

We have a custom Psalm plugin in our Tideways code base and I have added an automatic tests for empty including a suggest for the right replacement based on the type. Its not perfect and does not yet catch all different kinds of empty usages, but its a good enough start. See this Gist for the code and how to include it in your psalm.xml.

Published: 2021-02-19