У меня есть массив с деревом конфигурации:
$cfg = array('global' => array( 'project' => 'foo', 'base_url' => '/path/', 'charset' => 'utf-8', 'timezone' => 'Europe/Lisbon', 'environment' => 'development'), //... );
Мне нужно вставить элемент в дерево (или, возможно, изменить его), заданные строки, такие как "global:project"
и "bar"
где сначала задается путь к элементу и второй его значение. Таким образом, значение 'foo'
в $cfg['global']['project']
станет 'bar'
.
Вот функция, которая мне нужна:
function set_cfg($path, $value) { /* Alter $cfg with the given settings */ }
Поэтому я начинаю с того, что вы введете строку пути с помощью ':'
и получите массив с ключами пути:
$path = explode(':', $path)
Что дальше? Как я могу определить (рекурсивно?) Операцию вставки ключей в массив $cfg
?
function set_cfg($path, $value) { $path = explode(':', $path); $current = &$GLOBALS['cfg']; // variable is global, so get from $GLOBALS foreach ($path as $part) { $current = &$current[$part]; } $current = $value; }
Если вы можете быть уверены, что всегда будет только два уровня конфигурации, вы можете использовать:
function set_cfg($path, $value) { list($first, $second) = explode(':', $path, 2); $GLOBALS['cfg'][$first][$second] = $value; }
Добавьте массив в качестве ссылочного аргумента функции, а затем рекурсивно, пройдя по фрагменту массива, который вы хотите продолжить исследовать. Когда вы дойдете до конца, остановите (и присвойте значение ключу).
Это может показаться сумасшедшим, но что-то вроде этого:
eval("\$cfg['".str_replace(':', "']['", $path)."'] = ".var_export($value, true).';');
Я бы построил цикл, который проходит через каждый элемент в пути, когда в конце присваивает значение.
Следующий код касается обновления в соответствии с запросом, но он еще не имеет дело с пустыми узлами вдоль пути, если это может произойти (скорее всего), обязательно сделайте проверку в цикле и создайте новые массивы по мере необходимости.
$node=$cfg; $i=0; while($i<count($path)-1) { $node = $node[$path[$i]]; i++; } $node[$path[$i]]=$value;
в$node=$cfg; $i=0; while($i<count($path)-1) { $node = $node[$path[$i]]; i++; } $node[$path[$i]]=$value;