It can be really easy to get tripped up by PHP’s empty and isset functions. I just came across a bug in some code that was using empty()
to check for something so I thought this was a good time to remind others about this.
First a quick refresher course on isset()
and empty()
. The isset function only checks to see if a specific variable was been created and has a value other than NULL. Other than the NULL check isset doesn’t make any determinations on what value the variable holds. The empty function on the other hand looks at the value of a variable to see if it has been set to something that could be considered “empty”. The empty doc page mentions what PHP considers “empty”:
Returns FALSE if var has a non-empty and non-zero value.
The following things are considered to be empty:
“” (an empty string)
0 (0 as an integer)
“0” (0 as a string)
NULL
FALSE
array() (an empty array)
var $var; (a variable declared, but without a value in a class)
So with all that in mind, what would you expect from the following code:
[sourcecode lang=”php”]
$test_me = ‘ ‘;
if ( empty( $test_me ) ) {
echo "This is empty!n";
} else {
echo "NOT emptyn";
}
[/sourcecode]
Where $test_me is set to a string that contains a single space character. If you said ‘NOT empty’ was the result, you are correct. If you said ‘This is empty!’, well, I can understand why you’d think that, but that turned out to be the wrong answer.
This is exactly what happened in the bug I saw. An empty check was being done inside a foreach() loop to see if any work on that item in the array really needed to be done. If empty returned TRUE then continue was called to skip work on that item and go on to the next. Unfortunately it didn’t expect the condition where the value might just be a string full of spaces. To people that looks empty, to PHP, not so much.
[sourcecode lang=”php”]
foreach ( $stuff as $a_thing ) {
if ( empty( $a_thing ) ) {
continue;
}
…
}
[/sourcecode]
A good approach, until $a_thing includes our friend the string of spaces.
So how do you deal with this? PHP provides an rtrim function to remove trailing spaces (and space line items) and you might be tempted to try this:
[sourcecode lang=”php”]
if ( empty( rtrim( $test_me ) ) ) {
…
}
[/sourcecode]
But that won’t work. The empty function can only check variables, thankfully this is noted on the empty docs page:
Note: empty() only checks variables as anything else will result in a parse error. In other words, the following will not work: empty(trim($name)).
Not the end of the world, just means you have to write it like this:
[sourcecode lang=”php”]
$test_me = rtrim( $test_me );
if ( empty( $test_me ) ) {
…
}
[/sourcecode]
That will remove any trailing spaces from $test_me before the empty check, so strings that consist of just spaces (or space like characters) will truly become empty in the PHP sense.
If you’ve been writing PHP long enough you’ve likely run into this problem, it’s an easy one to get tripped on. I’ve lost count the number of times I’ve been bitten by this over the years. Perhaps writing this will save me (and hopefully others) from this mistake in the future.