我写了一个自定义框架。它使用配置文件的.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);