Arrays7 min readExamples run on PHP 8.5.10

key_exists()

Learn how key_exists(), the alias of array_key_exists(), checks whether an array has a key, and how it differs from isset() for null values.

Signature

key_exists(mixed $key, array $array): bool
Available since PHP 4.0.67.48.08.18.28.38.48.5All versions →

Purpose

key_exists() answers one question: does this array contain this key? It is an alias of array_key_exists(), so the two names call the same function and behave identically. Because the alias name is less common, most codebases and style guides prefer array_key_exists(). You will still meet key_exists() in older code, so it helps to know it is not a separate feature.

The check looks only at the keys of the array you pass in. It does not look at the values, and it does not search nested arrays.

Signature

The signature above is written as mixed for brevity. In practice $key should be something that can act as an array key: a string, an integer or a boolean. Passing null still works but is deprecated as of PHP 8.5. The function is documented as an alias of array_key_exists(), which is where the behavior comes from.

Parameters and defaults

  • $key: the key to look for. Neither parameter has a default value.
  • $array: the array to inspect. In PHP 8 this must be an array. Passing an object is a TypeError, so use property_exists() when you need to check object properties.

Return value and failure cases

The function returns true when the key is present and false when it is absent. A present key whose value is null still returns true. That is the main reason to choose this function over isset().

An unusable key type, such as an array, causes a TypeError. A missing key is not an error, it simply returns false.

Example 1: present, missing and null

This example compares key_exists() with isset() for a key whose value is null.

Example
<?php
$settings = ['theme' => 'dark', 'cache' => null, 'retries' => 0];
echo json_encode([
    'theme' => key_exists('theme', $settings),
    'cache_exists' => key_exists('cache', $settings),
    'cache_isset' => isset($settings['cache']),
    'missing' => key_exists('timeout', $settings),
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
{"theme":true,"cache_exists":true,"cache_isset":false,"missing":false}

The cache key exists, but isset() reports false because its value is null.

Example 2: key normalization

PHP normalizes array keys, and the lookup follows the same rules. A numeric string such as '1' matches the integer key 1. A boolean true is treated as 1. A null key is treated as the empty string, but PHP 8.5 deprecates it, so pass '' explicitly.

Example
<?php
$items = [1 => 'one', '' => 'empty', 'x' => 'ex'];
echo json_encode([
    key_exists('1', $items),
    key_exists(1, $items),
    key_exists(true, $items),
    key_exists('X', $items),
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
[true,true,true,false]

The last lookup is false because string keys are case-sensitive.

Example 3: honoring explicit nulls

A typical use is option handling. If the caller explicitly passes null, you may want to respect it rather than replace it with a default.

Example
<?php
function pick_options(array $input): array {
    $defaults = ['limit' => 10, 'offset' => 0, 'search' => 'all'];
    $result = [];
    foreach ($defaults as $name => $default) {
        $result[$name] = key_exists($name, $input) ? $input[$name] : $default;
    }
    return $result;
}

echo json_encode(pick_options(['limit' => 25, 'search' => null, 'extra' => 1]), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
{"limit":25,"offset":0,"search":null}

The search option stays null because the caller supplied it. The unknown extra key is ignored, and offset falls back to its default.

Edge cases

  • Only top-level keys are checked. For ['a' => ['b' => 1]], looking up 'b' returns false.
  • An empty array never contains any key.
  • Keys that look like integers are stored as integers, so '1' and 1 are the same key. A string such as '01' is not converted and is a different key.
  • Key lookup is case-sensitive for strings.
  • Arrays that contain false, 0, '' or null as values still report their keys as present.

Common mistakes

  1. Using isset() when null is meaningful. isset() returns false for a null value, so it cannot tell a null entry from a missing one.
  2. Searching values instead of keys. To test whether a value is in the array, use in_array() or array_search().
  3. Passing an object. PHP 8 requires an array as the second argument. Cast deliberately or use property_exists() instead.
  4. Expecting nested lookups. You must check each level separately, or combine checks as you walk down.
  5. Mixing alias names without a reason. Using both key_exists() and array_key_exists() in one project makes searching harder. Pick one name and keep it.
  • array_key_exists(): the canonical name of the same function.
  • isset(): a language construct that is also false for null values.
  • in_array() and array_search(): search values rather than keys.
  • array_keys(): list the keys of an array.
  • property_exists(): check properties on objects or classes.

Recap

key_exists() is a plain alias of array_key_exists(). It returns true when a key is present, even if the value is null, and false when it is absent. Remember that keys are normalized, string keys are case-sensitive, nested keys are not searched, and the second argument must be an array.

Tested examples

Present, missing and null values
<?php
$settings = ['theme' => 'dark', 'cache' => null, 'retries' => 0];
echo json_encode([
    'theme' => key_exists('theme', $settings),
    'cache_exists' => key_exists('cache', $settings),
    'cache_isset' => isset($settings['cache']),
    'missing' => key_exists('timeout', $settings),
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
{"theme":true,"cache_exists":true,"cache_isset":false,"missing":false}
Key normalization
<?php
$items = [1 => 'one', '' => 'empty', 'x' => 'ex'];
echo json_encode([
    key_exists('1', $items),
    key_exists(1, $items),
    key_exists(true, $items),
    key_exists('X', $items),
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
[true,true,true,false]
Honoring explicit nulls in options
<?php
function pick_options(array $input): array {
    $defaults = ['limit' => 10, 'offset' => 0, 'search' => 'all'];
    $result = [];
    foreach ($defaults as $name => $default) {
        $result[$name] = key_exists($name, $input) ? $input[$name] : $default;
    }
    return $result;
}

echo json_encode(pick_options(['limit' => 25, 'search' => null, 'extra' => 1]), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
{"limit":25,"offset":0,"search":null}