Функция array_intersect_ukey() в PHP
Узнайте, как работает array_intersect_ukey() в PHP: сравнение ключей массивов с пользовательской функцией и получение пересечения.
Функция array_intersect_ukey() сравнивает ключи двух и более массивов с помощью переданного вами callback-а и возвращает элементы первого массива, ключи которых присутствуют во всех остальных массивах. Буква u в названии означает пользовательскую функцию сравнения — это аналог array_intersect_key(), работающий с ключами, с той разницей, что вы сами определяете, когда два ключа считаются «одинаковыми».
На этой странице описано, что возвращает функция, как callback управляет результатом и на какие подводные камни стоит обратить внимание перед её использованием.
Когда её использовать?
Используйте array_intersect_ukey(), когда нужно оставить только элементы с пересекающимися ключами, но простого сравнения ключей на равенство недостаточно. Типичные случаи:
- Сопоставление ключей без учёта регистра — считать
Hostиhostодним ключом. - Нормализованные ключи — игнорировать пробелы, префиксы или различия в форматировании перед сравнением.
- Фильтрация массива конфигурации или запроса до ключей, присутствующих в списке разрешённых.
Если вам нужно только точное совпадение ключей, воспользуйтесь более простой встроенной функцией array_intersect_key() — callback не потребуется.
Синтаксис
array_intersect_ukey(
array $array1,
array $array2,
array ...$arrays,
callable $key_compare_func
): arrayПараметры и возвращаемое значение
| Параметр | Описание |
|---|---|
$array1 | Массив, из которого производится сравнение. Его значения попадают в результат. |
$array2, ...$arrays | Один или несколько массивов, с ключами которых производится сравнение. |
$key_compare_func | Последний аргумент: callback, принимающий два ключа. Должен возвращать целое число меньше, равное или больше 0, когда первый ключ соответственно меньше, равен или больше второго. |
Возвращает: array, содержащий все пары ключ-значение из $array1, чьи ключи совпадают с ключами всех остальных массивов. Ключ считается совпавшим, когда callback возвращает 0.
Примечание: значения берутся только из
$array1. Значения, хранящиеся под совпавшими ключами в других массивах, игнорируются — важны только их ключи.
Базовый пример
<?php
function key_compare_func($key1, $key2)
{
if ($key1 == $key2)
return 0;
else if ($key1 > $key2)
return 1;
else
return -1;
}
$array1 = ['a' => 'green', 'b' => 'brown', 'c' => 'blue', 'red' => 3];
$array2 = ['d' => 'green', 'b' => 'yellow', 'yellow' => 10, 'red' => 'game'];
$result = array_intersect_ukey($array1, $array2, 'key_compare_func');
print_r($result);
?>Вывод:
Array
(
[b] => brown
[red] => 3
)Callback сравнивает ключи так же, как оператор spaceship: возвращает 0 только при равенстве двух ключей. Ключи b и red присутствуют в обоих массивах, поэтому их элементы сохраняются — со значениями из $array1 (brown и 3), а не из $array2.
В современном PHP весь вспомогательный код можно заменить оператором spaceship (<=>):
<?php
$array1 = ['a' => 'green', 'b' => 'brown', 'c' => 'blue', 'red' => 3];
$array2 = ['d' => 'green', 'b' => 'yellow', 'red' => 'game'];
$result = array_intersect_ukey(
$array1,
$array2,
fn($k1, $k2) => $k1 <=> $k2
);
print_r($result);
?>Вывод:
Array
(
[b] => brown
[red] => 3
)Сопоставление ключей без учёта регистра
Именно здесь callback показывает себя с лучшей стороны. strcasecmp() уже возвращает целочисленное значение в соответствии с контрактом функции (0 при совпадении, без учёта регистра), поэтому его можно передать напрямую, чтобы сопоставлять ключи независимо от капитализации:
<?php
$config = ['Host' => 'localhost', 'PORT' => 8080, 'Debug' => true];
$defaults = ['host' => '0.0.0.0', 'port' => 80, 'timeout' => 30];
$shared = array_intersect_ukey($config, $defaults, 'strcasecmp');
print_r($shared);
?>Вывод:
Array
(
[Host] => localhost
[PORT] => 8080
)Host совпадает с host, а PORT — с port, несмотря на различия в регистре, поэтому оба остаются в результате. У Debug нет аналога в $defaults, поэтому он исключается. Обратите внимание: сохранённые ключи и значения в точности соответствуют тому, как они записаны в первом массиве.
Подводные камни
- Callback должен возвращать
0для совпадения. Распространённая ошибка — написать callback, возвращающий boolean ($k1 === $k2).true/falseприводятся к1/0, поэтому несовпадающие ключи могут случайно «совпасть». Всегда возвращайте целое число трёхстороннего сравнения. - Значения берутся только из первого массива. Если два массива имеют общий ключ, но разные значения, в результат попадёт значение из первого массива.
- Callback является последним аргументом, даже если вы передаёте три и более массива для сравнения.
- Для сравнения одновременно ключей и значений используйте
array_intersect_uassoc(); для обратной операции (ключи, которые не являются общими), используйтеarray_diff_ukey().
Заключение
array_intersect_ukey() фильтрует array до элементов, чьи ключи присутствуют во всех остальных массивах, используя ваше собственное определение равенства ключей. Используйте её для сопоставления ключей без учёта регистра или с нормализацией; прибегайте к array_intersect_key(), когда достаточно точного совпадения. Главное правило: callback должен возвращать 0 для равных ключей, а результирующие значения всегда берутся из первого массива.