Я пытаюсь создать многомерный массив, чьи части определяются строкой. Я использую .
как разделитель, и каждая часть (кроме последней) должна быть массивом
например:
config.debug.router.strictMode = true
Мне нужны такие же результаты, как если бы я набирал:
$arr = array('config' => array('debug' => array('router' => array('strictMode' => true))));
Эта проблема действительно заставила меня ходить по кругу, любая помощь ценится. Благодаря!
Предположим, что у нас уже есть ключ и значение в $key
и $val
, тогда вы можете сделать это:
$key = 'config.debug.router.strictMode'; $val = true; $path = explode('.', $key);
Построение массива слева направо:
$arr = array(); $tmp = &$arr; foreach ($path as $segment) { $tmp[$segment] = array(); $tmp = &$tmp[$segment]; } $tmp = $val;
И справа налево:
$arr = array(); $tmp = $val; while ($segment = array_pop($path)) { $tmp = array($segment => $tmp); } $arr = $tmp;
Я говорю, что все разбито, начните со значения и отступите оттуда, каждый раз через, обертывая то, что у вас есть в другом массиве. Вот так:
$s = 'config.debug.router.strictMode = true'; list($parts, $value) = explode(' = ', $s); $parts = explode('.', $parts); while($parts) { $value = array(array_pop($parts) => $value); } print_r($parts);
Определенно перепишите его, чтобы он проверил ошибки.
Ответ Гумбо выглядит неплохо.
Однако похоже, что вы хотите разобрать типичный файл .ini.
Подумайте о том, как использовать библиотечный код вместо того, чтобы кататься самостоятельно.
Например, Zend_Config отлично справляется с этим.
Мне очень нравится, что Джейсон Вольф отвечает на это.
Что касается возможных ошибок: да, но он дал отличную идею, теперь читателю нужно сделать это пуленепробиваемой.
Моя потребность была немного более простой: из списка с разделителями создайте массив MD. Я слегка изменил его код, чтобы дать мне именно это. Эта версия предоставит вам массив с или без строки определения или даже строки без разделителя.
Надеюсь, кто-то может сделать это еще лучше.
$parts = "config.debug.router.strictMode"; $parts = explode(".", $parts); $value = null; while($parts) { $value = array(array_pop($parts) => $value); } print_r($value);
// The attribute to the right of the equals sign $rightOfEquals = true; $leftOfEquals = "config.debug.router.strictMode"; // Array of identifiers $identifiers = explode(".", $leftOfEquals); // How many 'identifiers' we have $numIdentifiers = count($identifiers); // Iterate through each identifier backwards // We do this backwards because we want the "innermost" array element // to be defined first. for ($i = ($numIdentifiers - 1); $i >=0; $i--) { // If we are looking at the "last" identifier, then we know what its // value is. It is the thing directly to the right of the equals sign. if ($i == ($numIdentifiers - 1)) { $a = array($identifiers[$i] => $rightOfEquals); } // Otherwise, we recursively append our new attribute to the beginning of the array. else { $a = array($identifiers[$i] => $a); } } print_r($a);