Skip to content
Theory · Conditions · lesson 4 of 8

null, isset and empty

The condition if ($x) asks whether a value is truthy. But sometimes there is no variable $x in the program at all: nobody assigned it a value, or its name has a typo. What does the condition say then?

PHP
<?php

if ($nickname) { // ✗
    echo 'Hi, ', $nickname, "\n";
}
echo 'next', "\n";
TEXT
Warning: Undefined variable $nickname

The variable $nickname never got a value. PHP issues a warning, reads it as null, skips the branch and prints next. The program keeps running, but the warning points to a bug in the code, and it must not stay there.

Imagine you are looking for a sign with a town's name at the fork. There are three possible situations:

  • there is no sign at all: the variable is not defined;
  • the sign hangs there but is blank: the variable holds null;
  • something is written on the sign: the variable holds a value.

PHP has three tools for these checks, and they answer different questions.

Three checks

isset

isset($x) asks whether there is a sign with something written on it. The answer is true when the variable exists and its value is not null.

PHP
$city = 'Paris';
$phone = null;
var_dump(isset($city));  // bool(true)
var_dump(isset($phone)); // bool(false)
var_dump(isset($email)); // bool(false)

Let's go through it line by line:

  1. $city holds a string, so isset gives true.
  2. $phone holds null, and isset gives false.
  3. $email is not defined, and isset gives false without any warning.

Why is there no warning? isset is not a function but a language construct: a part of the language itself that checks the variable directly instead of receiving its value like a function. That is why a missing variable does not bother it.

Here the analogy and PHP part ways. At a fork, a blank sign is visible at once. But isset does not tell it from a missing one: for $phone = null and for an undefined variable alike, it gives false.

empty

empty($x) asks whether the sign is blank or missing altogether. The answer is true when the variable is missing or its value is falsy—from the same list as in a condition. In effect, empty($x) works like !isset($x) || !$x.

PHP
$count = 0;
$title = 'News';
var_dump(empty($count));   // bool(true)
var_dump(empty($title));   // bool(false)
var_dump(empty($missing)); // bool(true)

Let's go through it line by line:

  1. 0 is a falsy value, so empty($count) gives true, even though the variable is set.
  2. $title holds a non-empty string, and empty gives false.
  3. $missing is not defined: empty is a language construct too, and it quietly gives true.

is_null

is_null($x) asks whether the sign is blank, that is, whether the value is exactly null. The answer is true only for null. For 0 and '' it gives false, because those are real values.

But is_null is an ordinary function. To pass it a value, PHP first reads the variable, and for a missing one it issues the same warning as if does:

TEXT
Warning: Undefined variable $email

After the warning, is_null($email) still returns true: PHP reads a missing variable as null.

Comparing the three checks

Value of $xisset($x)empty($x)
no variablefalsetrue
nullfalsetrue
0 or ''truetrue
'Anna'truefalse

Interviewers often ask: "How do isset, empty and is_null differ?" The answer:

  • isset: the variable exists and is not null, with no warnings;
  • empty: the variable is missing or its value is falsy, with no warnings either;
  • is_null: the value is exactly null; it is a function, and it warns on a missing variable.

The ?? operator

As you already know, $a ?? $b gives $a when it is set and not null, and $b otherwise. It is isset in the form of an expression: $name = $nickname ?? 'guest'; works like isset($nickname) ? $nickname : 'guest' and also gets by without warnings.

Common mistake

A quantity from a form arrived as the string '0', and its presence was checked with empty:

PHP
$quantity = '0';
if (empty($quantity)) { // ✗
    echo 'enter a quantity', "\n";
} else {
    echo 'ordered: ', $quantity, "\n";
}

The program prints enter a quantity, even though the person entered zero: '0' is a falsy value, and empty treats it as blank. To tell "not filled in" from zero, check for absence and for the empty string separately: if (!isset($quantity) || $quantity === '').

Key points

  • isset($x) gives true when the variable exists and is not null, and it never warns.
  • empty($x) gives true for a missing variable and for any falsy value, 0 and '0' included.
  • is_null($x) checks only for null; it is a function, and it issues a warning on an undefined variable.
  • $a ?? $b is isset in the form of an expression.