key_exists

Checks whether a key exists in an array, even when its value is null; an alias of array_key_exists().

Signature
key_exists(string|int|float|bool|resource|null $key, array $array): bool
  • Added in PHP 4.0.6

Parameters

ParameterTypeDescription
$keystring|int|float|bool|resource|nullThe key to look for. Any value usable as an array index; floats and bools are cast to int, and null is cast to an empty string.
$arrayarrayThe array whose keys are checked. Only the first dimension is searched.

Return value

boolReturns true if the key is present in the array, false otherwise — true even when the key's value is null.

Errors

Throws a TypeError if array is not an array — objects have not been accepted since PHP 8.0.

Changelog

  • PHP 8.5.0Passing null as the key is deprecated; pass an empty string instead.
  • PHP 8.0.0The key parameter formally accepts bool, float, int, null, resource and string.
  • PHP 8.0.0Passing an object as array is no longer supported; use property_exists() instead.
  • PHP 7.4.0Passing an object as array was deprecated.

key_exists() is an alias of array_key_exists(). It answers one question: does this array have this key, whatever the value happens to be?

That last clause is the whole point. isset($arr['k']) returns false when the key is present but holds null, so isset() cannot tell "absent" from "explicitly null". key_exists() can. Reach for it whenever null is meaningful: a nullable database column, a JSON body where "middle_name": null means "we asked and there is none", or a settings array where a null override must beat a default.

The lookup is shallow — first dimension only. For $a['user']['id'] you need two checks, or the null-safe ?? operator if a null value would be acceptable anyway.

Which name to use

Write array_key_exists() in new code. The short alias predates the array_* naming convention and reads inconsistently next to array_key_first() and array_keys(). Behaviour is identical.

Two version notes matter: since PHP 8.0 the second argument must really be an array, since objects were deprecated in 7.4 and are now rejected — use property_exists() for those. And since PHP 8.5, passing null as the key is deprecated; pass '' instead.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Distinguish an absent JSON field from one explicitly set to null when validating a request body.
  • Check whether a config array supplies an option before falling back to a default.
  • Guard a cache lookup where null is itself a valid cached result.
  • Verify a CSV header row contains a required column name.

Frequently asked questions

What is the difference between key_exists and array_key_exists?

None at all — key_exists() is a registered alias of array_key_exists() with identical behaviour and performance. Prefer array_key_exists() in new code for consistency with the other array_* functions.

What is the difference between key_exists and isset?

isset() returns false when the key exists but its value is null, whereas key_exists() returns true. isset() is a language construct and slightly faster, so use it unless null is a value you need to distinguish from absence.

Does key_exists work on multidimensional arrays?

It only searches the first dimension. To reach a nested key, check each level: key_exists('user', $a) && key_exists('id', $a['user']).

More examples

Validating a JSON payload

The 'middle' row shows key_exists=yes but isset=no — the client sent the field with an explicit null. The 'nickname' row is no/no because it was never sent. If you validate with isset() alone you cannot tell those two cases apart.

Example · php
<?php
$payload = json_decode('{"name":"Ada","middle":null}', true);

foreach (['name', 'middle', 'nickname'] as $field) {
    printf("%-9s key_exists=%-3s isset=%s\n",
        $field,
        key_exists($field, $payload) ? 'yes' : 'no',
        isset($payload[$field]) ? 'yes' : 'no');
}

Overrides where null is a real value

Prints "timeout => NULL" and "retries => 3". The caller deliberately disabled the timeout by setting it to null, and key_exists() honours that. Using $overrides[$k] ?? $default instead would have silently restored 30.

Example · php
<?php
$defaults  = ['timeout' => 30, 'retries' => 3];
$overrides = ['timeout' => null];

foreach ($defaults as $k => $default) {
    $value = key_exists($k, $overrides) ? $overrides[$k] : $default;
    echo $k, ' => ', var_export($value, true), "\n";
}

The check is one level deep

The first call is false: 'id' lives in the nested array, not the top level. The third is true. The last line shows the other common mix-up — in_array() searches values, key_exists() searches keys.

Example · php
<?php
$data = ['user' => ['id' => 1, 'email' => null]];

var_dump(key_exists('id', $data));
var_dump(key_exists('user', $data));
var_dump(key_exists('id', $data['user']));
var_dump(in_array(1, $data['user'], true));

Discussion

  • Be the first to comment on this lesson.