php parse_ini_file oop & deep - PullRequest
       23

php parse_ini_file oop & deep

2 голосов
/ 20 апреля 2011

Я хотел бы использовать что-то вроде [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']

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

or `$ini->db->host1` 

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

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

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

Ответы [ 3 ]

4 голосов
/ 20 апреля 2011

Ну, тогда вам нужно постобработать массив результатов 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, чтобы снова сбросить последний уровень объекта. (Цикл for для определения последнего ключа $ работал бы лучше).

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

3 голосов
/ 20 апреля 2011
$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);
0 голосов
/ 18 марта 2012

У меня есть элегантное решение для вас. Эта реализация позволяет наследовать и векторы, используя точки, как наш коллеги "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 = production
x.y = 3

[oi: environment]
z = 5

...