In PHP, what is the difference between isset(), empty() and is_null(), and when does each return true?
answer
- set and not null
- empty means missing or falsy
- "0" is empty, "0.0" is not
- is_null warns on undefined
- two constructs, one function
basics
~20 sisset() 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
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 stringgo deeper
Recall the three definitions and the surprising rows: isset(null) is false, empty("0") is true, is_null() warns on an undefined variable.
Explain that isset and empty are language constructs that suppress undefined warnings, and when array_key_exists is needed instead.
Show where these checks cause production bugs, such as empty() rejecting a valid 0, and replace them with explicit presence and value checks.
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.