isset
Checks whether one or more variables are declared and hold a value other than null.
isset(mixed $var, mixed ...$vars): bool- Added in PHP 4.0
Parameters
| Parameter | Type | Description |
|---|---|---|
$var | mixed | The variable to be checked. |
$varsoptional | mixed | Further variables to check. All must be set for the result to be true. |
Return value
booltrue if every argument is set and not null, false otherwise.
Errors
isset() is a language construct, not a function: passing anything other than a variable, array element or property is a parse error, and it cannot be used as a callback or with named arguments.
isset() is a language construct that answers "does this variable exist and hold something other than null?" without emitting a warning when it does not. That warning-free behaviour is the whole point: $_GET['page'] raises Undefined array key if you touch it directly, but isset($_GET['page']) never does.
When to reach for it
Guard access to superglobals, decoded JSON, and deeply nested arrays. Because it takes multiple arguments and stops at the first failure, isset($a, $b, $c) replaces three separate checks — and it short-circuits, so nothing after the first missing value is evaluated.
For the extremely common "use it if present, otherwise a default" pattern, the null coalescing operator ?? is shorter and does the same suppression: $page = $_GET['page'] ?? 1;. Chained ?? and ?-> have replaced most defensive isset() calls in modern code.
What trips people up
isset() returns false for a key that exists with a null value. If the difference between "absent" and "explicitly null" matters — a JSON patch, a nullable database column — use array_key_exists() for arrays or property_exists() for objects.
On inaccessible object properties it triggers the __isset() magic method, so a class with __get() but no __isset() will report false for values __get() would happily return.
Example
When to use it
- Reading an optional query-string parameter without an undefined-key warning
- Checking several required POST fields in one call before processing a form
- Testing a nested config path such as isset($cfg['db']['host']) safely
Frequently asked questions
What is the difference between isset and empty?
isset() is false only when the variable is missing or null, while empty() is true for any falsy value including 0, "0", "" and []. Use isset() to check existence and empty() to check for a meaningful value.
Why does isset return false when the array key exists?
Because the key holds null, and isset() treats null as not set. Use array_key_exists() to confirm the key is present regardless of its value.
Should I use isset or the ?? operator?
Use ?? when you want a fallback value — $x = $arr['k'] ?? 'default' is shorter and suppresses the same warnings. Use isset() when you need the boolean itself, such as inside an if with other conditions.
More examples
Validating required form fields at once
All three keys exist, so isset() passes even though token is an empty string. isset() only proves presence; empty() is what catches blank submissions.
<?php
$post = ['email' => '[email protected]', 'password' => 'hunter2', 'token' => ''];
if (!isset($post['email'], $post['password'], $post['token'])) {
echo "A required field is missing\n";
} else {
echo "All fields present\n";
}
var_dump(isset($post['token']));
var_dump(empty($post['token']));Nested arrays and magic __isset
isset() walks a nested path without warning even when an intermediate level is absent. On the object, isset() calls __isset() rather than __get() — omit __isset() from such a class and every isset($obj->prop) check returns false.
<?php
$cfg = ['db' => ['host' => 'localhost']];
var_dump(isset($cfg['db']['host']));
var_dump(isset($cfg['db']['port']));
var_dump(isset($cfg['cache']['ttl']['deep']));
class Bag {
private array $d = ['a' => 1];
public function __get($k) { return $this->d[$k] ?? null; }
public function __isset($k) { return isset($this->d[$k]); }
}
$b = new Bag();
var_dump(isset($b->a), isset($b->z));
Discussion