When to use empty in PHP? I’d say never
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.
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.