php parse_ini_file oop & deep

Я хотел бы использовать somehting как [parse_ini_file] [1].

Скажем, например, у меня есть файл boot.ini, который я буду загружать для дальнейшей процедуры:

;database connection settings [database] type = mysql; host = localhost; username = root; password = ""; dbName = wit; 

Тем не менее, я хотел бы иметь его по-другому, поскольку массив php будет:

 $ini['database']['whatever'] 

Поэтому, прежде всего, я хотел бы, чтобы моя boot.ini была похожа на эту структуру:

 ;database settings (comment same style) db.host1.type = mysql; db.host1.host = localhost; db.host1.username = root; db.host1.password = ""; db.host1.dbName = wit; db.host2.type = mysql; db.host2.host = otherHost; db.host2.username = root; db.host2.password = ""; db.host2.dbName = wit; 

Поэтому, когда я получаю доступ к файлу, я хотел бы получить к нему доступ таким образом:

 $ini['db']['host1']['whatever'] 

И вдобавок к этому я хотел бы сделать это через ООП, поэтому давайте скажем: $ ini-> db-> host1-> whatever

 or `$ini->db->host1` 

вернет массив со всеми атрибутами, такими как тип, хост, имя пользователя, пароль и имя dbName;

Я ценю любую помощь. Заранее большое спасибо.

  [1]: http://uk2.php.net/manual/en/function.parse-ini-file.php 

Ну, тогда вам нужно выполнить постпроцесс массива результатов parse_ini_file .

 $ini_array = parse_ini_file("bootstrap.ini"); $ini = new stdclass; foreach ($ini_array as $key=>$value) { $c = $ini; foreach (explode(".", $key) as $key) { if (!isset($c->$key)) { $c->$key = new stdclass; } $prev = $c; $c = $c->$key; } $prev->$key = $value; } 

Обновите Hackety-Hack. Теперь используйте дополнительный $prev для повторного удаления последнего уровня объекта. (А для цикла, чтобы обнаружить последний ключ $, лучше работал бы).

Если вы хотите использовать синтаксис массива и синтаксис объекта, замените new stdclass new ArrayObject(array(), 2); ,

 $ini_array = parse_ini_file("sample.ini"); $ini = new stdclass; foreach ($ini_array as $key => $value) { $last = substr(strrchr($key, '.'), 1); if (!$last) $last = $key; $node = $ini; foreach (explode('.', $key) as $key2) { if (!isset($node->$key2)) { $node->$key2 = new stdclass; } if ($key2 == $last) { $node->$key2 = $value; } else { $node = $node->$key2; } } } var_dump($ini->db->host1->type); 

У меня есть элегантное решение для вас. Эта реализация позволяет наследованию и векторам использовать точки, поскольку наши коллеги «zerkms» показали нам раньше. По правде говоря, я принял его решение и улучшил его. Таким образом, решение похоже на Zend Parser 🙂 Я тестировал его и работает. Но, как мы знаем, невозможно проверить все возможности. Затем, надеюсь, внимательные люди обнаруживают проблемы и предлагают исправления.

Здесь идет код (как функция):

 function parse($filename) { $ini_array = parse_ini_file ( $filename, true ); if (! $ini_array) throw new Exception ( 'Error on parsing ini file!', - 1 ); $ini = new stdClass (); //Parse section... foreach ( $ini_array as $namespace => $prop ) { $section = $namespace; $ext = explode ( ':', $namespace ); if (count ( $ext ) == 2) { $section = trim ( $ext [0] ); $extend = trim ( $ext [1] ); if (! isset ( $ini->$extend )) throw new Exception ( 'Parent section doesn\'t exists!', - 1 ); $ini->$section = clone $ini->$extend; } else $ini->$section = new stdClass (); foreach ( $prop as $key => $value ) { $arr = explode ( '.', $key ); $n = count ( $arr ) - 1; if ($n) { $aux = $ini->$section; for($i = 0; $i < $n; ++ $i) { if(!isset($aux->$arr [$i])) $aux->$arr [$i] = new stdClass (); $aux = $aux->$arr [$i]; } $aux->$arr [$n] = $value; } else $ini->$section->$key = $value; } } return $ini; } 

И вот пример файла .ini:

[Окружающая среда]
env_name = производство
xy = 3

[oi: environment]
z = 5