Я написал пользовательскую структуру. Который использует конфигурационный файл .ini.
Скажем, если у меня есть константа, назначенная в файле .ini как
[production] db.mongo.hostName = localhost
В настоящее время я разбираю это через функцию parse_ini_file()
.
Результат будет
$config[production][db.mongo.hostname] = "localhost";
Теперь я хочу превратить этот массив в объект, который должен
$config->db->mongo->hostname
Я попытался взломать его с помощью '.'
, но затем я застрял в формировании этого как выше итерационного объекта.
Может кто-то, пожалуйста, помогите мне с этим.
Ниже приведен рудиментарный класс, который имеет единственную функцию для импорта массива ini, как вы его указали:
/** * Config "Class" * @link http://stackoverflow.com/q/11188563/367456 */ class Config { public function __construct(array $array = array()) { $this->importIniArray($array); } public function importIniArray(array $array) { foreach ($array as $key => $value) { $rv = &$this; foreach (explode('.', $key) as $pk) { isset($rv->$pk) || $rv->$pk = new stdClass; $rv = &$rv->$pk; } $rv = $value; } } }
Я только добавил функцию __construct
потому что вы повторно используете переменную. Применение:
$config = parse_ini_file($path); $config = new Config($config['production']); print_r($config);
Примерный вывод:
Config Object ( [db] => stdClass Object ( [mongo] => stdClass Object ( [hostname] => localhost [user] => root ) ) )
Изменить. Вы также можете решить проблему, чтобы найти элемент массива во время доступа. Я собрал небольшой пример, который ведет себя аналогично, и он ничего не взрывает. Я назвал его DynConfig
потому что, как вы увидите, это динамическое (или волшебное):
$config = new DynConfig($config['production']); var_dump($config); echo $config->db->mongo->hostname; # localhost
var_dump
показывает, что массив просто сохраняется внутри:
object(DynConfig)#1 (1) { ["array":"DynConfig":private]=> array(2) { ["db.mongo.hostname"]=> string(9) "localhost" ["db.mongo.user"]=> string(4) "root" } }
Так, как это работает? Каждый раз, когда вы получаете доступ к свойству, существует либо ключ, либо префикс, и тот же объект возвращается. Это в функции __get
:
/** * Config "Class" * @link http://stackoverflow.com/q/11188563/367456 */ class DynConfig { private $array; public function __construct($array) { $this->array = $array; } public function __get($name) { static $prefix = ''; $k = $prefix .= $name; if (isset($this->array[$k])) { $prefix = ''; return $this->array[$k]; } $prefix .= '.'; return $this; } }
Однако это экспериментальный характер. Первое предложение гораздо более прямое и гораздо легче справиться. Имейте в виду, что ваш конфигурационный объект должен быть очень простым, ему просто нужно сохранить некоторые значения, и все.
Вы можете сделать это, как показано ниже.
function assignTo($obj,$keys,$value) { if(count($keys) > 1) { $h = array_shift($keys); $obj->$h = $obj->$h ? $obj->$h : new stdClass(); assignTo($obj->$h,$keys,$value); } else { $obj->$keys[0] = $value; } } $config['production']['db.mongo.hostname'] = "localhost"; $config['production']['db.mongo.password'] = "1234567"; $config['production']['version'] = "1.0"; $object = new stdClass(); foreach($config['production'] as $key=>$value) { assignTo($object,explode('.',$key),$value); } print_r($object);
Что будет выводить:
stdClass Object ( [db] => stdClass Object ( [mongo] => stdClass Object ( [hostname] => localhost [password] => 1234567 ) ) [version] => 1.0 )
// assuming $var is a multidimensional array $obj = json_decode (json_encode ($var), FALSE);