PHPnews.io

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

Written by Benjamin Eberlei / Original link on Feb. 18, 2021

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:

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

testing that the string has length 0

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

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

Using strlen communicates that the variable is a string.

testing that array has no elements

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

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

Using count communicates that the variable is an array.

testing if array has key

// 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.

testing if a variable was declared in the scope

// 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.

testing if a variable is null

// 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.

testing if a variable is 0

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

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

Communicates that variable is integer.

testing if a variable is false

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

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

Communicates that variable is boolean.

What if?

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.

Automatic Enforcement

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.

beberlei

« Add Multiple Columns After a Column in Migrations - Use Alpine to Intercept a Form's Submission »