I am told that good developers can spot/utilize the difference between Null
and False
and 0
and all the other good "nothing" entities.
What is the difference, specifically in PHP? Does it have something to do with ===
?
Null
means "nothing". The var has not been initialized.
False
means "not true in a boolean context". Used to explicitly show you are dealing with logical issues.
0
is an int
. Nothing to do with the rest above, used for mathematics.
Now, what is tricky, it's that in dynamic languages like PHP, all of them have a value in a boolean context, which (in PHP) is False
.
If you test it with ==
, it's testing the boolean value, so you will get equality. If you test it with ===
, it will test the type, and you will get inequality.
Well, look at the strrpos()
function. It returns False if it did not found anything, but 0 if it has found something at the beginning of the string !
<?php
// pitfall :
if (strrpos("Hello World", "Hello")) {
// never exectuted
}
// smart move :
if (strrpos("Hello World", "Hello") !== False) {
// that works !
}
?>
And of course, if you deal with states:
You want to make a difference between DebugMode = False
(set to off), DebugMode = True
(set to on) and DebugMode = Null
(not set at all, will lead to hard debugging ;-)).
null
is null
. false
is false
. Sad but true.
there's not much consistency in PHP. the developers TRY to make null means "unkown" or "non-existent". but often False will serve as 'non-existent' (e.g. strrpos('fail', 'search') will return false, and not null)
you will often see null being used when they are already using false for something. e.g. filter_input(). They return false if the variable fails the filter. and null if the variable does not exists (does not existing means it also failed the filter? so why even return null?!?)
php has the convenience of returning data in the functions. and ofter the developers cram in all kind of failure status instead of the data.
And There's no sane way in PHP to detect data (int, str, etc) from failure (false, null)
you pretty much have to always test for ===null or ===false, depending on the function. or for both, in cases such as filter_input()/filter_var()
and here's some fun with type juggling. not even including arrays and objects.
var_dump( 0<0 ); #bool(false)
var_dump( 1<0 ); #bool(false)
var_dump( -1<0 ); #bool(true)
var_dump( false<0 ); #bool(false)
var_dump( null<0 ); #bool(false)
var_dump( ''<0 ); #bool(false)
var_dump( 'a'<0 ); #bool(false)
echo "\n";
var_dump( !0 ); #bool(true)
var_dump( !1 ); #bool(false)
var_dump( !-1 ); #bool(false)
var_dump( !false ); #bool(true)
var_dump( !null ); #bool(true)
var_dump( !'' ); #bool(true)
var_dump( !'a' ); #bool(false)
echo "\n";
var_dump( false == 0 ); #bool(true)
var_dump( false == 1 ); #bool(false)
var_dump( false == -1 ); #bool(false)
var_dump( false == false ); #bool(true)
var_dump( false == null ); #bool(true)
var_dump( false == '' ); #bool(true)
var_dump( false == 'a' ); #bool(false)
echo "\n";
var_dump( null == 0 ); #bool(true)
var_dump( null == 1 ); #bool(false)
var_dump( null == -1 ); #bool(false)
var_dump( null == false ); #bool(true)
var_dump( null == null ); #bool(true)
var_dump( null == '' ); #bool(true)
var_dump( null == 'a' ); #bool(false)
echo "\n";
$a=0; var_dump( empty($a) ); #bool(true)
$a=1; var_dump( empty($a) ); #bool(false)
$a=-1; var_dump( empty($a) ); #bool(false)
$a=false; var_dump( empty($a) ); #bool(true)
$a=null; var_dump( empty($a) ); #bool(true)
$a=''; var_dump( empty($a) ); #bool(true)
$a='a'; var_dump( empty($a)); # bool(false)
echo "\n"; #new block suggested by @thehpi
var_dump( null < -1 ); #bool(true)
var_dump( null < 0 ); #bool(false)
var_dump( null < 1 ); #bool(true)
var_dump( -1 > true ); #bool(false)
var_dump( 0 > true ); #bool(false)
var_dump( 1 > true ); #bool(true)
var_dump( -1 > false ); #bool(true)
var_dump( 0 > false ); #bool(false)
var_dump( 1 > true ); #bool(true)