Question

isset() vs array_key_exists() in PHP: Key Existence and Null Values

Question

How do these two PHP expressions differ when checking an array?

isset($a['key']);
array_key_exists('key', $a);

In particular, how does each expression behave when the key is missing, present with a non-null value, or present with a null value?

Short Answer

You will learn how PHP's isset() and array_key_exists() check arrays differently. The key distinction is that isset() returns false for a value of null, while array_key_exists() returns true when the key exists even if its stored value is null.

Concept

isset() and array_key_exists() can both appear to answer “does this array key exist?”, but they test different things.

  • isset($array['key']) checks whether the array offset is set and not null.
  • array_key_exists('key', $array) checks whether the key is stored in the array, regardless of its value.

Consider this array:

$user = [
    'name' => 'Mina',
    'middle_name' => null,
];
isset($user['name']);          // true
isset($user['middle_name']);   // false
isset($user['age']);           // false

array_key_exists('name', $user);         // true
array_key_exists('middle_name', $user);  // true
array_key_exists('age', $user);          // false

This matters because null can have meaning in an application. It may represent a deliberately empty database field, an API property explicitly set to null, or a configuration option intentionally cleared. Choose the function based on whether you care about a usable non-null value or the key's actual presence.

Mental Model

Think of an array as a set of labelled drawers.

  • array_key_exists() asks: “Is there a drawer with this label?” A drawer counts even if it contains nothing (null).
  • isset() asks: “Is there a drawer with this label that contains a value other than null?” A labelled drawer containing null is treated as unavailable.

So isset() is usually a quick “can I safely use this value?” check, while array_key_exists() is a precise “was this key provided?” check.

Take Quiz

Syntax and Examples

Use isset() with an array offset:

isset($array['key']);

Use array_key_exists() with the key first and the array second:

array_key_exists('key', $array);

Example:

$settings = [
    'theme' => 'dark',
    'timezone' => null,
    'notifications' => false,
];

var_dump(isset($settings['theme']));
// bool(true)

var_dump(isset($settings['timezone']));
// bool(false)

var_dump(isset($settings['notifications']));
// bool(true) -- false is still a non-null value

var_dump(array_key_exists('timezone', $settings));
// bool(true)

isset() does not reject values such as false, 0, 0.0, '', or []. It returns false only when the variable or offset does not exist, or when its value is null.

Step by Step Execution

Trace this example:

$profile = [
    'email' => null,
    'active' => false,
];

$emailIsUsable = isset($profile['email']);
$emailWasProvided = array_key_exists('email', $profile);
$activeExists = isset($profile['active']);
$roleExists = array_key_exists('role', $profile);
  1. $profile['email'] has a key named email, but its value is null.
  2. isset($profile['email']) returns false because isset() treats null as not set.
  3. array_key_exists('email', $profile) returns true because email is a real key in the array.
  4. $profile['active'] contains false, which is non-null. Therefore, isset($profile['active']) returns true.
  5. There is no role key, so array_key_exists('role', $profile) returns false.

Real World Use Cases

  • Optional API fields: Distinguish a field omitted by the client from one explicitly sent as null.
  • Patch-style updates: A request with "nickname": null may mean “clear the nickname,” whereas a missing nickname field means “leave it unchanged.” Use array_key_exists().
  • Configuration defaults: Use isset() when a missing or null setting should both fall back to a default.
  • Rendering templates: Use isset() before displaying an optional value that must be non-null.
  • Data imports: Use array_key_exists() when validating that a CSV or decoded JSON record contains required columns, even if some values may be null.
Take Quiz

Real Codebase Usage

In production PHP code, the choice often reflects the business rule.

Default when absent or null

$language = isset($config['language']) ? $config['language'] : 'en';

If language is missing or null, this uses 'en'.

With PHP's null coalescing operator, the same pattern is shorter:

$language = $config['language'] ?? 'en';

?? has isset()-style behavior: it uses the fallback when the value is missing or null.

Detect an explicitly supplied field

if (array_key_exists('display_name', $input)) {
    $user->setDisplayName($input['display_name']);
}

This is appropriate for update endpoints because display_name => null can be intentionally handled by setDisplayName().

Guard clauses

if (!isset($session['user_id'])) {
    throw new RuntimeException('You must be signed in.');
}

Here, a null user ID should not be accepted, so isset() is a natural fit.

Common Mistakes

Assuming isset() means the key definitely exists

$data = ['status' => null];

if (isset($data['status'])) {
    // This does not run.
}

The key exists, but the value is null. Use array_key_exists('status', $data) if that distinction matters.

Assuming false makes isset() return false

$flags = ['enabled' => false];
var_dump(isset($flags['enabled'])); // true

isset() is not a truthiness test. It only treats missing values and null as false.

Reversing array_key_exists() arguments

// Incorrect
array_key_exists($data, 'status');

The key comes first:

array_key_exists('status', $data);

Using empty() to test key presence

$values = ['count' => 0];
var_dump(empty($values['count'])); // true

empty() returns true for values such as 0, false, and '', so it is not a reliable key-existence check.

Using array_key_exists() on an object

array_key_exists() is for arrays. For object properties, use tools designed for objects, such as property_exists() when you specifically need to know whether a property is declared or present.

Comparisons

CheckMissing keyKey with nullKey with false or 0Main purpose
isset($a['key'])falsefalsetrueCheck for a non-null value
array_key_exists('key', $a)falsetruetrueCheck whether an array contains the key
empty($a['key'])truetruetrueCheck whether a value is empty/falsy
$a['key'] ?? $default$default$defaultkeeps valueProvide a fallback for missing or null values

Use isset() when missing and null should be handled the same way. Use array_key_exists() when those cases must remain different.

Take Quiz

Cheat Sheet

// True only if the offset exists and is not null
isset($array['key']);

// True if the key exists, including keys whose value is null
array_key_exists('key', $array);

// Default for a missing or null offset
$value = $array['key'] ?? 'default';
  • isset() returns true for false, 0, '', and [].
  • isset() returns false for missing offsets and null values.
  • array_key_exists() distinguishes a missing key from a key mapped to null.
  • empty() is for emptiness, not reliable key presence.
  • Use array_key_exists() only when the null distinction is meaningful.

FAQ

Does isset() return true for false in PHP?

Yes. isset() returns true for false, 0, an empty string, and an empty array. It returns false only for missing values and null.

Why does isset($array['key']) return false when the key is in the array?

The key's value is likely null. isset() requires both key availability and a non-null value.

When should I use array_key_exists() instead of isset()?

Use it when your program must distinguish between a missing key and a key explicitly set to null.

Is the null coalescing operator ?? like isset()?

Yes. $array['key'] ?? $default uses the default when the key is missing or its value is null.

Can I use array_key_exists() to check object properties?

No. It is intended for arrays. Consider property_exists() for object-property checks, depending on the behavior you need.

Should I use empty() to check whether an array key exists?

Usually no. empty() also treats valid values such as 0, false, and '' as empty.

Take Quiz

Mini Project

Description

Build a small profile-update function that distinguishes fields omitted from an incoming request from fields intentionally set to null. This models a common API update scenario.

Goal

Update only supplied profile fields while allowing a supplied null value to clear the nickname.

Requirements

  1. Create a profile array with a name, nickname, and newsletter preference.
  2. Create an update array that changes the newsletter preference and clears the nickname with null.
  3. Update only fields that are present in the update array.
  4. Preserve profile fields that are absent from the update array.
  5. Use array_key_exists() where null must be treated as an intentionally supplied value.
Take Quiz

Keep learning

Related questions

View more