1

我写了一个自定义框架。它使用 .ini 类型的配置文件。

说,如果我在 .ini 文件中分配了一个常量

[production]
db.mongo.hostName = localhost

我目前正在通过parse_ini_file()函数解析这个。

结果将是

$config[production][db.mongo.hostname] = "localhost";

现在我想把这个数组变成一个对象,它应该像

$config->db->mongo->hostname

我尝试用 爆炸它'.',但后来我坚持将它形成为上面的迭代对象。

有人可以帮我解决这个问题。

4

3 回答 3

3

以下是一个基本类,它具有一个函数来导入您指定的 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;
    }
}

然而,这是实验性质的。第一个建议更直接,也更容易处理。请记住,您的配置对象应该非常简单,它只需要存储一些值即可。

于 2012-06-25T14:00:07.153 回答
2

您可以按以下方式完成

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
)
于 2012-06-25T12:00:33.083 回答
0
// assuming $var is a multidimensional array
$obj = json_decode (json_encode ($var), FALSE);
于 2012-12-07T11:20:09.607 回答