PHP – содержимое массива lookup с синтаксисом точки

Кто-нибудь видит что-то не так со следующей функцией? ( Изменить : нет, я не думаю, что что-то не так, я просто проверю дважды, так как это будет вставлено в очень распространенный путь к коду.)

function getNestedVar(&$context, $name) { if (strstr($name, '.') === FALSE) { return $context[$name]; } else { $pieces = explode('.', $name, 2); return getNestedVar($context[$pieces[0]], $pieces[1]); } } 

Это, по сути, преобразует:

 $data, "fruits.orange.quantity" 

в:

 $data['fruits']['orange']['quantity'] 

Для контекста, это для формы, которую я создаю в Smarty. Мне также нужно имя для формы, поэтому мне нужна строка в форме на основе ключа и не может напрямую обращаться к переменной Smarty в Smarty.

Solutions Collecting From Web of "PHP – содержимое массива lookup с синтаксисом точки"

Попробуйте итеративный подход:

 function getNestedVar(&$context, $name) { $pieces = explode('.', $name); foreach ($pieces as $piece) { if (!is_array($context) || !array_key_exists($piece, $context)) { // error occurred return null; } $context = &$context[$piece]; } return $context; } 

Взгляните на это: https://gist.github.com/elfet/4713488

 $dn = new DotNotation(['bar'=>['baz'=>['foo'=>true]]]); $value = $dn->get('bar.baz.foo'); // $value == true $dn->set('bar.baz.foo', false); // ['foo'=>false] $dn->add('bar.baz', ['boo'=>true]); // ['foo'=>false,'boo'=>true] 

И этот класс также имеет тесты PHPUnit.

Насколько глубоко это гнездование будет? PHP имеет ограничение на рекурсию, похоже, ок. 2 ^ 16. Просто протестировал это и на глубине рекурсии 65420 PHP (5.2.9) молчал (без ошибок).

В его текущей форме ошибки / предупреждения не отображаются, если один или несколько элементов не существуют

 error_reporting(E_ALL|E_STRICT); ini_set('display_errors', 1); $x = array(); getNestedVar($x, '1.2.3.4'); echo 'done.'; 

(тестируется с помощью php 5.3.1 / win32).
По какой-то причине доступ к несуществующему элементу в getNestedVar($context[$pieces[0]]... не вызывает предупреждения, что очень затрудняет отладку и находит, например, опечатку.

Я не вижу ничего плохого в этом коде. Я тоже тестировал его.

Отвечает ли это на ваш вопрос?

Изменить: Это ИМХО немного лучше. Он не использует рекурсию и возвращает null в случае доступа к дочернему элементу без массива.

 function getNestedVar(array $array, $name) { $name = explode('.', $name); foreach($name as $namePart) { if (is_array($array)) return null; if (!isset($array[$name])) return null; $array = $array[$name]; } return $array; } 

ура

Почему вы не просто используете html .. name="fruit[orange]" достаточно .. сделать массив.

Посмотрите @ http://github.com/projectmeta/Stingray

Позволяет читать и записывать массив через точечную нотацию / синтаксис.

Пример: http://github.com/projectmeta/Stingray#example-usage