Задать вопрос

Есть ли в PHP готовый инструмент для получения элемента массива вложенность которого хранится в другом массиве?

Здравствуйте!
Есть ли в языке PHP какой либо штатный функционал для получения элемента массива вложенность которого храниться в другом массиве, то есть предположим есть некоторый массив:

$ar = array(
  "z" => array(
    "x" => array(
      "c" => array(
        "v" => array(
          "a" => 123,
          "b" => 321
        )
      )
    )
  )
);


И массив который хранит вложенность нужного элемента:
$path = array("z","x","c");

И соответственно вопрос в стандартном PHP инструменте для получения $ar["z"]["x"]["c"]; Может быть для этого есть что то в Reflection?

Примеры самописных функций приводить не требуется, поскольку есть например такой ресурс https://translated.turbopages.org/proxy_u/en-ru.ru... просто на всякий случай решил спросить может есть какой то стандартный подход чтобы не писать свой велосипед?
  • Вопрос задан
  • 240 просмотров
Подписаться 1 Простой 4 комментария
Пригласить эксперта
Ответы на вопрос 4
delphinpro
@delphinpro Куратор тега PHP
frontend developer
Штатных средств нет.
Неким "стандартом" стал доступ в dot-нотации. Вот одна из реализаций:
https://github.com/adbario/php-dot-notation
Ответ написан
ipatiev
@ipatiev Куратор тега PHP
Потомок старинного рода Ипатьевых-Колотитьевых
Есть. Называется цикл.
Ответ написан
Комментировать
@maksam07
<?php
function getNestedValue($array, $path) {
    foreach ($path as $key) {
        if (!isset($array[$key])) {
            return null;
        }
        $array = $array[$key];
    }
    return $array;
}

$ar = array(
  "z" => array(
    "x" => array(
      "c" => array(
        "v" => array(
          "a" => 123,
          "b" => 321
        )
      )
    )
  )
);

$path = array("z", "x", "c");

$result = getNestedValue($ar, $path);

echo $result !== null ? "Значение: " . print_r($result, true) : "Элемент не найден";
?>
Ответ написан
@rPman
С академической точки зрения, если это не в продакшен и только похвастаться, можно воспользоваться eval:
$myfunc = eval('return function($x) { return $x['.implode('][',array_map('json_encode',$path)).']; };');
echo json_encode($myfunc($ar)); // {"v":{"a":123,"b":321}}

Тут array_map('json_encode',$path)) экранирует всякие ковычки и слеши, преобразуя значения в код для их получения
Затем полученный массив с помощью implode('][',... превращается в последовательный вызов элементов этого многомерного массива.
А eval('return function($x) { return $x[...]]; };'); формирует строку функции для вызова этой конструкции и помещает ее в переменную.
Затем остается только вызвать это $myfunc($ar);

Формально это очень должна быть самая быстрая реализация (сделайте кто-нибудь бенчмарк, для разных размеров ключей и сложности исходного массива), из недостатков только отсутствие контроля за ошибками (чтобы понять, какой именно элемент отсутствует, нужно либо парсить лог ошибок, что рекомендуется, либо добавлять в генерируемую функцию проверки, что сильно замедлит результат)... вроде других проблем не будет, все экранировано.

p.s. если структура $path неизменна для проекта, я бы рекомендовал генерацию кода перед запуском (т.е. прямо .php файлы генерировать) а не во время, это будет еще быстрее и эффективнее, да и поддерживать этот бред будет понятнее.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы