Why I Avoid Using empty() in PHP? A Closer Look

Abdelaziz M
3 min readSep 10, 2024

--

One of the most useful yet widely misunderstood functions in PHP is empty(). At first glance, empty() seems like a handy shortcut for checking if a variable is, well, empty. However, its behavior goes beyond the obvious. According to the PHP documentation, empty() considers the following values as "empty":

  • "" (empty string)
  • 0 (integer)
  • 0.0 (float)
  • "0" (string)
  • NULL
  • FALSE
  • array() (empty array)
  • var $var; (a declared but uninitialized class variable)

This broad range of “empty” values can sometimes cause unexpected behavior in your code, especially in production environments. Let’s look at why relying on empty() can be risky and what alternatives can be used to write more robust and predictable code.

The Problem with empty()

The problem arises when empty() treats values like 0, "0", or false as empty. This behavior may lead to unwanted results when you're dealing with numeric or boolean data that should be treated differently from strings or null values.

Let’s consider a scenario where using empty() might cause an issue. Imagine you receive a JSON response with data like this:

{
"place_name": "some name",
"distance": "0.0"
}

When you read this data into an array and cast the distance to a float:

$distance = (float) $data['distance'];
if (empty($distance)) {
echo "Error: Distance is not set!"; // This evaluates to true, even though $distance is 0.0
}

Here, you’d expect the quantity to be valid since 0 is a legitimate number. However, because empty() treats 0 as "empty", the condition will incorrectly output "Quantity is empty!". In cases where 0 is a valid input (such as counting or pricing scenarios), this can introduce bugs into your application.

A Better Alternative: Strict Comparisons

Instead of using empty(), I’ve adopted a more explicit approach when checking values, especially in production environments where accuracy is crucial. Here’s how I typically handle such cases:

$distance = (float) $data['distance'];

if ('' === $distance) {
echo "Distance is empty string!";
} elseif (0 === $distance) {
echo "Distance is zero!";
} elseif (null === $distance) {
echo "Distance is null!";
} else {
echo "Distance is valid!";
}

By checking for exact values using strict comparisons (===), you can ensure that only the specific cases you're interested in are caught, avoiding unwanted behavior.

Real-World Example: Production Bugs

In a previous project, we had an issue where a form submission kept failing because a numeric field was evaluated using empty(). The users were submitting valid data like 0, but the backend was rejecting it, assuming the input was invalid. After a lengthy debugging session, we realized that empty() was treating 0 as "empty", causing our validation to fail unexpectedly.

We resolved the issue by replacing empty() with strict comparisons, ensuring that 0 and other edge cases were handled correctly:

$price = $_POST['price']; // User input from a form

if (null === $price || '' === $price) {
echo "Price is required!";
} elseif (0 === (int) $price) {
echo "Price is zero!";
} else {
echo "Price is valid!";
}

Why the Name empty() Can Be Misleading

From a naming perspective, empty() suggests that it only checks for empty values like an empty string or an empty array. However, its behavior covers a broader spectrum, including 0 and false, which can cause confusion and unexpected results.

For developers who are new to PHP or those who rely on assumptions about how functions work based on their names, this can be a source of bugs. That’s why I believe it’s important to review PHP’s native functions regularly, even the ones you think you know well, to avoid surprises in your code.

Conclusion

While empty() can be convenient in some cases, it’s essential to understand its behavior fully before using it in your code, especially in production environments. By using strict comparisons (===), you can write more predictable and robust code, reducing the chances of unexpected issues.

So, the next time you’re tempted to use empty(), consider whether it's the right tool for the job. Being precise in your checks can save you a lot of headaches down the line.

--

--