использовать строки для доступа (потенциально больших) многомерных массивов

У меня возникли проблемы с выяснением способа простого анализа ввода строки и поиска правильного местоположения в многомерном массиве.

Я надеюсь на одну или две линии, чтобы сделать это, поскольку решения, которые я видел, полагаются на длинные (10-20 строк) петли.

Учитывая следующий код (обратите внимание, что вложение может теоретически иметь любую произвольную глубину):

function get($string) { $vars = array( 'one' => array( 'one-one' => "hello", 'one-two' => "goodbye" ), 'two' => array( 'two-one' => "foo", 'two-two' => "bar" ) ); return $vars[$string]; //this syntax isn't required, just here to give an idea } get("two['two-two']"); //desired output: "bar". Actual output: null 

Есть ли простое использование встроенных функций или что-то еще легкое, что бы воссоздать мой желаемый результат?

Учитывая, что $vars являются вашими переменными, вы хотели бы получить one['one-one'] или two['two-two']['more'] из ( Demo ):

 $vars = function($str) use ($vars) { $c = function($v, $w) {return $w ? $v[$w] : $v;}; return array_reduce(preg_split('~\[\'|\'\]~', $str), $c, $vars); }; echo $vars("one['one-one']"); # hello echo $vars("two['two-two']['more']"); # tea-time! 

Это лексирование строки в ключевые токены, а затем перемещение массива $vars по $vars значениям, а массив $vars – в функцию.


Старые вещи:

Перегрузите массив с помощью функции, которая просто имеет значение eval:

 $vars = array( 'one' => array( 'one-one' => "hello", 'one-two' => "goodbye" ), 'two' => array( 'two-one' => "foo", 'two-two' => "bar" ) ); $vars = function($str) use ($vars) { return eval('return $vars'.$str.';'); }; echo $vars("['one']['one-two']"); # goodbye 

Если вы не поклонник eval, измените реализацию:

 $vars = function($str) use ($vars) { $r = preg_match_all('~\[\'([az-]+)\']~', $str, $keys); $var = $vars; foreach($keys[1] as $key) $var = $var[$key]; return $var; }; echo $vars("['one']['one-two']"); # goodbye 

Как насчет

 $vars = array( 'one' => array( 'one-one' => "hello", 'one-two' => "goodbye" ), 'two' => array( 'two-one' => "foo", 'two-two' => "bar" ) ); function get( $string, $vars ) { $keys = explode( '][', substr( $string, 1, -1 ) ); foreach( $keys as $key ) { $vars = $vars[$key]; } return $vars; } echo get( '[two][two-one]', $vars ); 

Например, у вас нет функции $var в вашей функции get() . $ var был определен вне функции, а правила определения PHP не делают «более высокие» вары видимыми в более низких областях, если они явно не сделаны глобальными в нижней области:

 function get($string) { global $vars; eval('$x = $vars' . $string); return $x; } get("['two']['two-two']"); 

может работать, но это не проверено, и использование eval – почти всегда очень плохая идея.

В Kohana есть хороший класс Config, в котором есть что-то вроде этого:

 echo Config::get("two.two-two"); 

Вы можете проверить это здесь: http://kohanaframework.org/3.1/guide/api/Config