2012-06-25 65 views
1

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

说,如果我在.ini文件分配一个常数

[production] 
db.mongo.hostName = localhost 

我目前通过parse_ini_file()功能解析此。

其结果将是

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

现在我想关闭这个数组的对象,它应该像

$config->db->mongo->hostname 

我试着用'.'爆炸了,但后来我坚持形成该作为上面的迭代对象。

有人可以帮助我这个。

+1

精确复制:http://stackoverflow.com/questions/1869091/convert-array-to-object-php?rq=1 – Dev

+1

Zend_Config_Ini的已经这样做了相当不错。 –

+0

Jon,谢谢,我已经看到了Zend ini解析器,它们遵循它解析的某种模式。它是一个巨大的功能。我从zend转移的主要原因是,它太多了我正在做的应用程序... – Karthik

回答

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函数,因为您重新使用v良莠不齐。用法:

$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; 
    } 
} 

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

+0

我已经在我的Config类中使用了php魔术函数和单例模式...谢谢...这太酷了... DynConfigAccess nis很酷.. – Karthik

+1

不,实际上我犯了一个错误,这并不需要第二课。我编辑答案。并且不要使用单体反模式,从长远来看,魔术也不是真的有用。你会引入问题。 – hakre

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 
) 
+0

非常感谢你湖。 – Karthik

+0

:),我很高兴它的帮助,不客气@Karthik – Lake

+1

@Lake:如果你想学习一些技巧,看看这个重复的问题,它的答案是:http://stackoverflow.com/ q/8537148/367456 – hakre

0
// assuming $var is a multidimensional array 
$obj = json_decode (json_encode ($var), FALSE);