skip to content

In PHP, what is the difference between isset(), empty() and is_null(), and when does each return true?

level: juniorimportance: must knowfreq 72%

answer

  1. set and not null
  2. empty means missing or falsy
  3. "0" is empty, "0.0" is not
  4. is_null warns on undefined
  5. two constructs, one function

basics

~20 s

isset() is true when a variable exists and is not null. empty() is true when it is missing or falsy, such as 0, "0", "" or []. is_null() is a function, true only for null, and warns on undefined variables.

solid answer

~40 s

`isset($x)` returns true if the variable **exists and is not null**; it accepts several arguments (all must be set) and never warns. `empty($x)` is essentially `!isset($x) || $x == false`: true for a missing variable and for every **falsy** value, including `0`, `0.0`, `""`, `"0"`, `[]`, `null` and `false`, but not `"0.0"` or `" "`. Both are **language constructs**, so they do not warn on undefined variables, keys or properties, and they call `__isset()` on inaccessible properties. `is_null($x)` is an ordinary **function**: it returns true only for `null`, and on an undefined variable PHP 8 raises an `E_WARNING` first. The trap: `empty()` treats `"0"` as empty, so it is wrong for validating user input, and `isset()` is false for a key that exists with a `null` value.

code

php · 11 lines
php
<?php
declare(strict_types=1);

$reading = ['station' => 'north', 'temp' => 0.0, 'wind' => null];

var_dump(isset($reading['temp']));              // bool(true)
var_dump(empty($reading['temp']));              // bool(true): 0.0 is falsy
var_dump(isset($reading['wind']));              // bool(false): null
var_dump(array_key_exists('wind', $reading));   // bool(true)
var_dump(isset($reading['rain']['mm']));        // bool(false), no warning
var_dump(empty('0.0'));                         // bool(false): non-empty string

go deeper

for a junior

Recall the three definitions and the surprising rows: isset(null) is false, empty("0") is true, is_null() warns on an undefined variable.

for a middle

Explain that isset and empty are language constructs that suppress undefined warnings, and when array_key_exists is needed instead.

for a senior

Show where these checks cause production bugs, such as empty() rejecting a valid 0, and replace them with explicit presence and value checks.

for a principal

Push input handling toward typed request objects and validation layers so scattered isset and empty checks disappear from business code.

## Three questions, three tools The three checks answer different questions: - **`isset($x)`**: does this variable exist, with a value other than `null`? - **`empty($x)`**: is this variable missing, or does its value convert to `false`? - **`is_null($x)`**: is this value `null`? ## Truth table | Value of `$x` | `isset($x)` | `empty($x)` | `is_null($x)` | |---|---|---|---| | undefined | false | true | true, with a warning | | `null` | false | true | true | | `false` | true | true | false | | `0` / `0.0` | true | true | false | | `""` | true | true | false | | `"0"` | true | true | false | | `"0.0"` | true | false | false | | `" "` (a space) | true | false | false | | `[]` | true | true | false | | `[0]` | true | false | false | The `empty()` column is PHP's list of values that convert to `false`: `false`, `0`, `0.0` and `-0.0`, `""` and `"0"`, an empty array, and `null`. Every other string, including `"0.0"` and `"false"`, is truthy. ## isset() - It is a **language construct**, not a function. It accepts only variables, array elements and properties; `isset(getValue())` is a parse error. - It takes several arguments: `isset($a, $b['k'])` is true only if all are set, evaluated left to right and stopping at the first unset one. - It never raises a warning, however deep the path: `isset($reading['sensor']['temp'])` is safe when `sensor` is missing. - On an inaccessible property it calls the class's `__isset()` method if one is declared. - It returns **false for `null`**. For an array key that exists with a `null` value, `isset()` says false while `array_key_exists()` says true. ## empty() - Also a language construct, with no warning for undefined variables or nested keys. - The manual describes it as the concise equivalent of `!isset($var) || $var == false`. - Unlike `isset()`, it also accepts an arbitrary expression, such as `empty(trim($input))`. Its weakness is the definition of falsy. A form field containing `"0"`, a count of `0` or a temperature of `0.0` is a real value, and `empty()` reports it as missing. Use it only where every falsy value genuinely means "nothing here". ## is_null() - An ordinary **function** with the signature `is_null(mixed $value): bool`. - Because the argument is evaluated before the call, an undefined variable first triggers PHP's undefined-variable diagnostic, an `E_WARNING` since PHP 8.0 (it was a notice before), and then `is_null()` receives `null` and returns true. - `$x === null` does the same check without a function call and is the more common spelling in modern code. ## Choosing in practice 1. **Optional input or config key that may be absent**: `isset()`, or the null coalescing operator for a default, which is its own topic. 2. **Key that may legitimately hold `null`**: `array_key_exists()`. 3. **"Nothing useful here" where `0` and `"0"` also count as nothing**: `empty()`, deliberately. 4. **A value you know exists and may be null**: `$x === null`. 5. **Validating user input**: none of these alone. Check presence with `isset()`, then validate the value itself, for example with `trim($v) !== ''` or a numeric check. The interview answer that stands out gives the table's surprising rows: `isset(null)` is false, `empty("0")` is true, `empty("0.0")` is false, and `is_null()` warns on an undefined variable while the other two do not.

  • Why is empty() a poor choice for validating a submitted form field?
    Because it treats `"0"` as empty. A user who enters `0` for a quantity or rating would be told the field is required. Check presence with `isset()` and then validate the value itself, for example `trim($value) !== ''` for a required text field or a numeric check for a number.
  • isset() returns false for a key you can see in the array; how is that possible?
    The key exists but holds `null`. `isset()` is true only for existing, non-null values. Use `array_key_exists('key', $array)` when the difference between "missing" and "present but null" matters.

saying these in an interview costs you the question

  • isset() returns true for a variable that holds null.
  • empty("0.0") is true because it looks like zero.
  • is_null() is a language construct that never warns on undefined variables.
  • empty() is the right way to check a required form field.
  • isset() and array_key_exists() always give the same answer.