NULL & isset / empty
null is PHP's way of representing "no value." It is its own type with exactly one possible value, written as the bare keyword null (case-insensitive, though lowercase is the convention). A variable can be explicitly set to null, or it can simply never have been assigned at all — and PHP gives you three different functions, isset(), empty(), and is_null(), to distinguish between those situations, each with subtly different rules that are worth learning precisely rather than guessing at.
What null actually means
Assigning and checking null
<?php $middleName = null; var_dump($middleName); var_dump($middleName === null); var_dump(gettype($middleName));
NULL bool(true) string(4) "NULL"
A variable holding null still exists — it has been assigned a value, that value just happens to be "nothing." This is different from a variable that was never assigned to at all, which is the first source of confusion this page untangles.
is_null()
is_null($value) is the most literal check: it returns true only when the value is exactly null, and behaves identically to $value === null. It does not care whether the variable was ever defined — checking an undefined variable with is_null() still works, but as of PHP 8 it raises a warning for accessing an undefined variable, just like reading it directly would.
is_null() vs strict comparison
<?php $a = null; $b = 0; var_dump(is_null($a)); // bool(true) var_dump(is_null($b)); // bool(false) - 0 is not null var_dump($a === null); // bool(true) - identical check
bool(true) bool(false) bool(true)
isset()
isset($variable) answers a slightly different question: "does this variable exist, and is its value anything other than null?" A variable that was never assigned returns false. A variable explicitly set to null also returns false — which surprises people expecting isset() to just mean "has this been assigned." Critically, isset() never raises a warning or notice even when the variable does not exist, which is exactly why it is the standard guard for optional data.
isset() across three situations
<?php $city = "Nairobi"; $region = null; // $country was never assigned var_dump(isset($city)); // bool(true) var_dump(isset($region)); // bool(false) - explicitly null var_dump(isset($country)); // bool(false) - undefined, no warning
bool(true) bool(false) bool(false)
isset() also works on array keys and object properties, and this is where it is used most often in real code: isset($_GET['page']) safely checks for a query-string parameter that may or may not be present, without triggering a warning for the missing key.
empty()
empty($variable) asks a broader question again: "is this variable either unset, or does it hold a falsy value?" It is essentially !isset($variable) || !$variable, bundled into one function that also never warns about undefined variables.
empty() catches more cases than isset()
<?php $votes = 0; $name = ""; $items = ["apple"]; var_dump(empty($votes)); // bool(true) - 0 is falsy var_dump(empty($name)); // bool(true) - "" is falsy var_dump(empty($items)); // bool(false) - non-empty array is truthy var_dump(empty($missing)); // bool(true) - undefined, no warning
bool(true) bool(true) bool(false) bool(true)
Truth table: isset() vs empty() vs is_null()
Value | isset() | empty() | is_null() |
|---|---|---|---|
undefined variable | false | true | true (with warning) |
| false | true | true |
| true | true | false |
| true | true | false |
| true | true | false |
| true | true | false |
| true | true | false |
| true | false | false |
A preview of the null coalescing operator
The pattern isset($value) ? $value : $default is common enough that PHP 7 introduced a dedicated shorthand: the null coalescing operator, ??. It evaluates its left-hand side and returns it if it exists and is not null, otherwise it returns the right-hand side — with no warning either way.
?? replacing an isset() ternary
<?php $page = $_GET['page'] ?? 1; echo $page;
1
isset()andempty()can be called on undefined variables, array keys, and object properties without ever raising a warning — this is their main practical advantage over direct access.is_null()requires the variable to already exist (as of PHP 8, accessing an undefined one first raises a warning); preferisset()when existence itself is in question.empty($x)is equivalent to!isset($x) || !$x, so it treats0,"0", and""the same as an unset variable.