W3docs

Функция 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 для равных ключей, а результирующие значения всегда берутся из первого массива.

Практика

Практика
Какова цель функции array_intersect_ukey() в PHP?
Какова цель функции array_intersect_ukey() в PHP?
Was this page helpful?