Hi everyone, you programmers trying to grasp the intricacies of PHP. As coders, our raw material is, and will be, information and knowledge. But lack of knowledge does not give us some information, too? Is of this absence that we will discuss today: How to know if we don't know something in PHP. And our main tools are isset
, is_null
and empty
. Want to know more about them? Which one is The Good, The Bad and The Ugly?
The Question
So, our question is not only "what do we know" but, more specifically, "How do our tools behave against different values of a variable?". Let's talk about our "falsy values" and then check them with our tools:
- undefined
- There's no var in scope with that name or it was removed with
unset
. The end. Finito. Capput. That's not a value itself, but it's a possible state of a variable. - null
- Our beloved friend
null
is a valid value, but in this state the variable is considered to be not setted. - false
- The falsy value par excelence. PHP has a native boolean type and it's a valid state.
- zero
- The integer value
0
is also a common false value for any programming language. - empty string
- A zero-length string, like
''
. - zero string
- A string containing only the zero character, like this:
'0'
. - empty array
- The simplest array of all, an array with no elements, like
array()
. - empty object
- An object with no members defined, like
(object)array()
ornew StdClass
.
The Code
In order to test how our tools behave with falsy values, I coded the following snippet:
function bool2str($bool)
{
return $bool ? 'true' : 'false';
}
// Detects command line
define('IS_CLI', php_sapi_name() === 'cli');
// Define initial state
unset($undef);
$null = null;
$false = false;
$zero = 0;
$empty = '';
$zeroStr = '0';
$array = array();
$object = (object)$array;
// Show PHP Version
echo (IS_CLI ? '' : '<pre>'),
'PHP Version: ', phpversion(), PHP_EOL;
// !isset() tests
echo '!isset($undef) : ', bool2str(!isset($undef)), PHP_EOL,
'!isset($null) : ', bool2str(!isset($null)), PHP_EOL,
'!isset($false) : ', bool2str(!isset($false)), PHP_EOL,
'!isset($zero) : ', bool2str(!isset($zero)), PHP_EOL,
'!isset($empty) : ', bool2str(!isset($empty)), PHP_EOL,
'!isset($zeroStr) : ', bool2str(!isset($zeroStr)), PHP_EOL,
'!isset($array) : ', bool2str(!isset($array)), PHP_EOL,
'!isset($object) : ', bool2str(!isset($object)), PHP_EOL,
PHP_EOL;
// is_null() tests
echo 'is_null($undef) : ', bool2str(is_null($undef)), PHP_EOL,
'is_null($null) : ', bool2str(is_null($null)), PHP_EOL,
'is_null($false) : ', bool2str(is_null($false)), PHP_EOL,
'is_null($zero) : ', bool2str(is_null($zero)), PHP_EOL,
'is_null($empty) : ', bool2str(is_null($empty)), PHP_EOL,
'is_null($zeroStr) : ', bool2str(is_null($zeroStr)), PHP_EOL,
'is_null($array) : ', bool2str(is_null($array)), PHP_EOL,
'is_null($object) : ', bool2str(is_null($object)), PHP_EOL,
PHP_EOL;
// empty() tests
echo 'empty($undef) : ', bool2str(empty($undef)), PHP_EOL,
'empty($null) : ', bool2str(empty($null)), PHP_EOL,
'empty($false) : ', bool2str(empty($false)), PHP_EOL,
'empty($zero) : ', bool2str(empty($zero)), PHP_EOL,
'empty($empty) : ', bool2str(empty($empty)), PHP_EOL,
'empty($zeroStr) : ', bool2str(empty($zeroStr)), PHP_EOL,
'empty($array) : ', bool2str(empty($array)), PHP_EOL,
'empty($object) : ', bool2str(empty($object)), PHP_EOL,
PHP_EOL;
echo (IS_CLI ? '' : '</pre>');
Note how I've used !isset
in order to maintain coherence with is_null
and empty
returning false
for setted values. Let's see the results!
The Good: !isset
state | result | notes |
---|---|---|
undefined | ✔ | |
null | ✔ | As expected |
false | ✘ | |
zero | ✘ | |
empty string | ✘ | |
zero string | ✘ | |
empty array | ✘ | |
empty object | ✘ |
Our best friend in the "what we don't know" problem is isset
without doubt. Use it whenever you need to check for existence of a variable. Since it's a construction of the language, it doesn't choke on the non-existent variable. When the variable exists, and it's not null, will return true
.
isset
does not work on expressions, so isset(functionCall())
will always throw a parser error.
The Bad: is_null
state | result | notes |
---|---|---|
undefined | ✔ | Throws a notice, since is_null is a function! |
null | ✔ | |
false | ✘ | |
zero | ✘ | |
empty string | ✘ | |
zero string | ✘ | |
empty array | ✘ | |
empty object | ✘ |
is_null
is great for doing one thing, and it should be clear reading it's name: checks if a variable value is null. But if the variable isn't set, there is no value to check for!
Use it wisely, but only when you know the variable exists.
The Ugly: empty
state | result | notes |
---|---|---|
undefined | ✔ | |
null | ✔ | |
false | ✔ | |
zero | ✔ | This is somehow we can expect… |
empty string | ✔ | |
zero string | ✔ | Surprise! String-to-number attacks! |
empty array | ✔ | |
empty object | ✘ | On PHP < 5, returns true |
empty
is a language construct too smart for me. Like isset
, it only works on variable names, so empty(0)
does not work. It can detect undefined ones, but it also returns true for other values, even doing things like automatic conversion between types, and inconsistencies. Like the following code:
$double = 0.0;
echo bool2str(empty($double)); // Prints TRUE!!
$double = '0.0';
echo bool2str(empty($double)); // Prints false
Conclusion
isset
is your best bet to check for variable existence. If completeness is a must, I use isset($variable) && !is_null($variable)
, but it's a bit tricky. I also try to avoid magic, so I only use empty
when I truly need it's whole range of smart cumbersomeness.
Hope this helps someone not to make the mistakes I did in my past.
And always remember: When you have to shoot, shoot. Don't talk.
No comments:
Post a Comment