PHP isset() vs empty() vs is_null() vs if($var) vs null coalesce (??)

Estimated reading time of this article: 6 minutes

How can variables be tested in PHP whether they are set?

PHP has statements, operators and different functions which can be used to test the value of a variable. Three useful functions for this are isset(), empty() and is_null(). All these function return a boolean value. If these functions are not used in correct way they can cause unexpected results.

The blog post PHP isset() vs empty() vs is_null() by Virendra Chandak from 2012 gives a good comparison of isset(), empty() and is_null(). I've enhanced his article with if ($var) and $var ?? '-' (Null Coalesce Operator).

Comparison

isset() and empty() are often viewed as functions that are opposite, however this is not always true. The differences between these functions will be shown here.

isset()

From PHP manual – isset():

isset — Determine if a variable is declared and is different than NULL

In other words, it returns true when the variable is not null.

empty()

From PHP Manual – empty():

empty — Determine whether a variable is empty

In other words, it will return true if the variable is an empty string, false, array(), NULL, "0", 0, and an unset variable.

is_null()

From PHP Manual – is_null():

is_null — Finds whether a variable is NULL

In other words, it returns true only when the variable is null. is_null() is opposite of isset(), except for one difference that isset() can be applied to unknown variables, but is_null() only to declared variables.

if ($var)

From PHP Manual – if:

If expression evaluates to TRUE, PHP will execute statement

The boolean evaluation is described in PHP Manual – Converting to boolean

$var ?? '-' (Null Coalesce Operator) or
$var ??= '-' (Null Coalescing Assignment Operator)

From PHP Manual – Null Coalescing Operator:

The expression (expr1) ?? (expr2) evaluates to expr2 if expr1 is NULL, and expr1 otherwise.

In particular, this operator does not emit a notice if the left-hand side value does not exist, just like isset(). This is especially useful on array keys.

The Null Coalescing Assignment Operator $a ??= $b is a shorthand for $a = $a ?? $b. It exists since PHP 7.4.

Reference table

The table below is an easy reference for what these functions will return for different values. The blank spaces means the function returns bool(false).

Value of variable ($var)isset($var)empty($var)is_null($var)if($var)$var ?? '-' / $var ??= '-'
Null Coalesce
"" (an empty string)bool(true) bool(true) string(0) ""
" " (space)bool(true) truestring(1) " "
" " (two spaces)bool(true) truestring(2) " "
FALSEbool(true) bool(true)
TRUEbool(true) truebool(true)
array() (an empty array)bool(true) bool(true) array(0) { }
new stdClass() (an empty object)bool(true) trueobject(stdClass)#145 (0) { }
NULL bool(true) bool(true) string(1) "-"
"0" (0 as a string)bool(true) bool(true) string(1) "0"
0 (0 as an integer)bool(true) bool(true) int(0)
0.0 (0 as a float)bool(true) bool(true) float(0)
var $var; (a variable declared, but without a value) bool(true) bool(true) string(1) "-"
"\0" (NULL byte)bool(true) truestring(1) ""

I have tested the above values in following PHP versions:

  • 7.4.11

Source code

<?php
echo '<div>PHP version is ' . phpversion() . '</div>';
echo '<table border="1px solid" cellspacing="0" cellpadding="0">';
echo '<thead>';
echo '<tr>';
echo '<th>Value of variable ($var)</th>';
echo '<th>isset($var)</th>';
echo '<th>empty($var)</th>';
echo '<th>is_null($var)</th>';
echo '<th>if($var)</th>';
echo '<th>$var ?? \'-\'<br>Null Coalesce Operator (since PHP 7.0)</th>';
echo '</tr>';
echo '</thead>';
echo '<tbody>';
$var = '';
echo '<tr><td>"" (an empty string)</td><td>';
var_dump(isset($var));
echo '</td><td>';
var_dump(empty($var));
echo '</td><td>';
var_dump(is_null($var));
echo '</td><td>';
echo ($var) ? 'true' : 'false';
echo '</td><td>';
$result = (($var) ?? '-');
var_dump($result);
echo '</td></tr>';

$var = ' ';
echo '<tr><td>" " (space)</td><td>';
var_dump(isset($var));
echo '</td><td>';
var_dump(empty($var));
echo '</td><td>';
var_dump(is_null($var));
echo '</td><td>';
echo ($var) ? 'true' : 'false';
echo '</td><td>';
$result = (($var) ?? '-');
var_dump($result);
echo '</td></tr>';

$var = '  ';
echo '<tr><td>"  " (two spaces)</td><td>';
var_dump(isset($var));
echo '</td><td>';
var_dump(empty($var));
echo '</td><td>';
var_dump(is_null($var));
echo '</td><td>';
echo ($var) ? 'true' : 'false';
echo '</td><td>';
$result = (($var) ?? '-');
var_dump($result);
echo '</td></tr>';

$var = false;
echo '<tr><td>false</td><td>';
var_dump(isset($var));
echo '</td><td>';
var_dump(empty($var));
echo '</td><td>';
var_dump(is_null($var));
echo '</td><td>';
echo ($var) ? 'true' : 'false';
echo '</td><td>';
$result = (($var) ?? '-');
var_dump($result);
echo '</td></tr>';

$var = FALSE;
echo '<tr><td>FALSE</td><td>';
var_dump(isset($var));
echo '</td><td>';
var_dump(empty($var));
echo '</td><td>';
var_dump(is_null($var));
echo '</td><td>';
echo ($var) ? 'true' : 'false';
echo '</td><td>';
$result = (($var) ?? '-');
var_dump($result);
echo '</td></tr>';

$var = true;
echo '<tr><td>true</td><td>';
var_dump(isset($var));
echo '</td><td>';
var_dump(empty($var));
echo '</td><td>';
var_dump(is_null($var));
echo '</td><td>';
echo ($var) ? 'true' : 'false';
echo '</td><td>';
$result = (($var) ?? '-');
var_dump($result);
echo '</td></tr>';

$var = TRUE;
echo '<tr><td>TRUE</td><td>';
var_dump(isset($var));
echo '</td><td>';
var_dump(empty($var));
echo '</td><td>';
var_dump(is_null($var));
echo '</td><td>';
echo ($var) ? 'true' : 'false';
echo '</td><td>';
$result = (($var) ?? '-');
var_dump($result);
echo '</td></tr>';

$var = array();
echo '<tr><td>array() (an empty array)</td><td>';
var_dump(isset($var));
echo '</td><td>';
var_dump(empty($var));
echo '</td><td>';
var_dump(is_null($var));
echo '</td><td>';
echo ($var) ? 'true' : 'false';
echo '</td><td>';
$result = (($var) ?? '-');
var_dump($result);
echo '</td></tr>';

$var = new stdClass();
echo '<tr><td>new stdClass() (an empty object)</td><td>';
var_dump(isset($var));
echo '</td><td>';
var_dump(empty($var));
echo '</td><td>';
var_dump(is_null($var));
echo '</td><td>';
echo ($var) ? 'true' : 'false';
echo '</td><td>';
$result = (($var) ?? '-');
var_dump($result);
echo '</td></tr>';

$var = NULL;
echo '<tr><td>NULL</td><td>';
var_dump(isset($var));
echo '</td><td>';
var_dump(empty($var));
echo '</td><td>';
var_dump(is_null($var));
echo '</td><td>';
echo ($var) ? 'true' : 'false';
echo '</td><td>';
$result = (($var) ?? '-');
var_dump($result);
echo '</td></tr>';

$var = '0';
echo '<tr><td>"0" (0 as a string)</td><td>';
var_dump(isset($var));
echo '</td><td>';
var_dump(empty($var));
echo '</td><td>';
var_dump(is_null($var));
echo '</td><td>';
echo ($var) ? 'true' : 'false';
echo '</td><td>';
$result = (($var) ?? '-');
var_dump($result);
echo '</td></tr>';

$var = 0;
echo '<tr><td>0 (0 as an integer)</td><td>';
var_dump(isset($var));
echo '</td><td>';
var_dump(empty($var));
echo '</td><td>';
var_dump(is_null($var));
echo '</td><td>';
echo ($var) ? 'true' : 'false';
echo '</td><td>';
$result = (($var) ?? '-');
var_dump($result);
echo '</td></tr>';

$var = 0.0;
echo '<tr><td>0.0 (0 as a float)</td><td>';
var_dump(isset($var));
echo '</td><td>';
var_dump(empty($var));
echo '</td><td>';
var_dump(is_null($var));
echo '</td><td>';
echo ($var) ? 'true' : 'false';
echo '</td><td>';
$result = (($var) ?? '-');
var_dump($result);
echo '</td></tr>';

unset($var); // make sure $var is actually not defined
$var;
echo '<tr><td>var $var; (a variable declared, but without a value)</td><td>';
var_dump(isset($var));
echo '</td><td>';
var_dump(empty($var));
echo '</td><td>';
var_dump(is_null($var));
echo '</td><td>';
echo ($var) ? 'true' : 'false';
echo '</td><td>';
$result = (($var) ?? '-');
var_dump($result);
echo '</td></tr>';

$var = "\0";
echo '<tr><td>NULL byte ("\\0")</td><td>';
var_dump(isset($var));
echo '</td><td>';
var_dump(empty($var));
echo '</td><td>';
var_dump(is_null($var));
echo '</td><td>';
echo ($var) ? 'true' : 'false';
echo '</td><td>';
$result = (($var) ?? '-');
var_dump($result);
echo '</td></tr>';

echo '</tbody></table>';

Live demo

Execution of code as live demo.