Как перейти в многоуровневый массив, чтобы получить значение, основанное на массиве имен ключей?

Приведен следующий массив имен ключей в следующем формате (количество полей может изменяться):

$field_names = Array
(
[0] => web
[1] => results
[2] => result
[3] => title
)

Я хотел бы получить доступ к значению ключа содержимого следующего многоуровневого массива:

$values=stdClass Object(
[web] => Array(
[results] => Array(
[result] => Array(
[title] => Array(
[type] => default
[content] => Sample content
)
)
)
)
)

Пример примера того, как можно получить доступ к значению из приведенных выше массивов:

$value = $values->{$field_names[0]}[$field_names[1]][$field_names[2]][$field_names[3]]['content'];

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

Код выглядит так:

$field = array_shift($field_names);
$value = $values->$field;
foreach ($field_names as $field) {
if (is_array($value)) {
$value = $value[$field];
}
}

Я пытался сделать грязный патч, как:

$value = is_string($value[$field]) ? $value[$field] : $value[$field]['content'];

И это сработало для одного примера, но не работает для всех случаев, как один выше.

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

Есть ли простой способ получить доступ к значению многоуровневого массива, имеющего динамический массив имен ключей?

1

Решение

Рекурсивные решения также могут быть простыми

Ваши данные:

$field_names = Array("web", "results","result","title");
$values->web["results"]["result"]["title"]=
Array("type"=> "default", "content"=>"Sample content");

Функция:

function getField($obj, $keys) {
return ($key=array_shift($keys)) ? getField($obj[$key], $keys) : $obj["content"];
}

echo getField((Array)$values, $field_names);

Но если вы хотите не рекурсивный, вот он:

$obj=(Array)$values;
while ($key=array_shift($field_names)) $obj=$obj[$key];
echo $obj['content'];
2

Другие решения

Вот простой способ, не рекурсивный с использованием ссылки (взят из Как написать getter / setter для доступа к многоуровневому массиву по именам ключей?):

function get($object, $path) {
$prop = array_shift($path);
$temp =& $object->$prop;

foreach($path as $key) {
$temp =& $temp[$key];
}
return $temp;
}

$value = get($values, $field_names)['content']; //PHP 5.4.0
1

По вопросам рекламы [email protected]