Array key exists: примеры (PHP)
array_key_exists(string|int $key, array $array): boolОписание функции array_key_exists
Функция array_key_exists() проверяет наличие заданного ключа или индекса в массиве. Её применение актуально для проверки существования элемента перед его использованием, что помогает избежать ошибок уровня Notice (неопределенный индекс).
Функция принимает два обязательных аргумента:
- $key (mixed) - Проверяемое значение ключа. Функция преобразует ключ к целому числу, если это возможно.
- $array (array) - Массив, в котором происходит проверка ключа.
Возвращаемое значение - bool (true, если ключ существует, и false в противном случае).
Базовые примеры использования
$array = ['first' => 1, 'second' => 2, 5 => 'five'];
var_dump(array_key_exists('first', $array));
var_dump(array_key_exists(5, $array));
var_dump(array_key_exists('5', $array)); // Строка '5' преобразуется в число
var_dump(array_key_exists('third', $array));bool(true) bool(true) bool(true) bool(false)
$array = ['key' => null];
var_dump(array_key_exists('key', $array));
var_dump(isset($array['key']));bool(true) bool(false)
Похожие функции в PHP
Функция isset() проверяет, установлена ли переменная (или элемент массива) и не равна ли она null. Для ключа со значением NULL array_key_exists() вернет true, а isset() - false. Функция isset() также работает с обычными переменными.
key_exists() является псевдонимом array_key_exists(), они идентичны.
Эти функции проверяют наличие значения в массиве, а не ключа.
Функцию array_key_exists() предпочтительнее использовать, когда необходимо точно определить наличие ключа, даже если его значение равно NULL. Функция isset() больше подходит для общей проверки возможности обращения к элементу без генерации ошибок.
Аналоги в других языках
Array key exists в Python
В Python для словарей используется оператор in, который проверяет наличие ключа.
dictionary = {'first': 1, 'second': 2}
print('first' in dictionary)
print('third' in dictionary)True False
Array key exists в Javascript
В JavaScript можно использовать методы hasOwnProperty() или оператор in (который также проверяет цепочку прототипов).
let obj = { first: 1, second: 2 };
console.log(obj.hasOwnProperty('first'));
console.log('first' in obj);
console.log('third' in obj);true true false
Array key exists в MySQL
Прямого аналога нет, но для проверки существования поля в JSON-документе используется функция JSON_CONTAINS_PATH().
SELECT JSON_CONTAINS_PATH('{"a": 1, "b": 2}', 'one', '$.a');1
Типичные ошибки
Функция не работает с вложенными массивами рекурсивно.
$array = ['level1' => ['level2' => 'value']];
// Неверно:
var_dump(array_key_exists('level2', $array));
// Верно:
var_dump(array_key_exists('level2', $array['level1'] ?? []));bool(false) bool(true)
Ключ '5' будет преобразован в целое число 5.
$array = [5 => 'value'];
var_dump(array_key_exists('5', $array));bool(true)
// До PHP 8.0
var_dump(array_key_exists('key', null));
// Начиная с PHP 8.0 будет выброшена TypeError// До PHP 8.0: bool(false) с предупреждением. // PHP 8.0+: Fatal error: Uncaught TypeError...
Изменения в новых версиях PHP
Теперь при передаче аргумента $array, не являющегося массивом (array или объектом, реализующим интерфейс ArrayAccess), выбрасывается исключение TypeError. Ранее функция возвращала false и могла вызвать предупреждение.
В PHP 5.3 и ранее существовала возможность вызова array_key_exists() с объектом в качестве второго аргумента, но эта возможность была удалена в PHP 5.4. В PHP 7.4 добавлена возможность передачи объекта, реализующего ArrayAccess, но с ограничениями.
Расширенные примеры
function array_key_exists_recursive($key, array $array) {
if (array_key_exists($key, $array)) {
return true;
}
foreach ($array as $value) {
if (is_array($value) && array_key_exists_recursive($key, $value)) {
return true;
}
}
return false;
}
$multiArray = ['a' => ['b' => ['c' => 'value']]];
var_dump(array_key_exists_recursive('c', $multiArray));bool(true)
class TestArrayAccess implements ArrayAccess {
private $container = [];
public function offsetSet($offset, $value): void {
if (is_null($offset)) {
$this->container[] = $value;
} else {
$this->container[$offset] = $value;
}
}
public function offsetExists($offset): bool {
return isset($this->container[$offset]);
}
public function offsetUnset($offset): void {
unset($this->container[$offset]);
}
public function offsetGet($offset): mixed {
return $this->container[$offset] ?? null;
}
}
$obj = new TestArrayAccess();
$obj['test'] = 'data';
var_dump(array_key_exists('test', $obj)); // Работает, т.к. реализован ArrayAccessbool(true)
function array_keys_exist(array $keys, array $array): bool {
return !array_diff_key(array_flip($keys), $array);
}
$data = ['id' => 1, 'name' => 'John', 'email' => 'john@example.com'];
var_dump(array_keys_exist(['id', 'name'], $data));
var_dump(array_keys_exist(['id', 'age'], $data));bool(true) bool(false)
Функция isset() является языковой конструкцией и обычно работает быстрее, но она возвращает false для ключа со значением NULL.