2010-09-15 184 views
4

對於我的項目,我編寫了一個小配置類,它從.ini文件加載其數據。它會覆蓋魔術__get()方法,以提供對(只讀)配置值的簡化訪問。「Array chaining」的最佳解決方案

例config.ini.php:

;<?php exit; ?> 
[General] 
auth = 1 
user = "halfdan" 

[Database] 
host = "127.0.0.1" 

我的配置類(單例模式 - 在這裏的簡化)看起來像這樣:

class Config { 
    protected $config = array(); 

    protected function __construct($file) { 
     // Preserve sections 
     $this->config = parse_ini_file($file, TRUE); 
    } 

    public function __get($name) { 
     return $this->config[$name]; 
    } 
} 

載入的配置會產生這樣的陣列結構:

array(
    "General" => array(
    "auth" => 1, 
    "user" => "halfdan" 
), 
    "Database" => array(
    "host" => "127.0.0.1" 
) 
) 

可以通過做訪問數組的第一級,以及使用Config::getInstance()->General['user']的值。我真正想要的是通過做Config::getInstance()->General->user(語法糖)來訪問所有配置變量。該數組不是一個對象,「 - >」沒有定義,所以這只是失敗。

我想到了一個解決方案,並希望得到一些關於它的輿論:

class Config { 
    [..] 
    public function __get($name) { 
    if(is_array($this->config[$name])) { 
     return new ConfigArray($this->config[$name]); 
    } else { 
     return $this->config[$name]; 
    } 
    } 
} 

class ConfigArray { 
    protected $config; 

    public function __construct($array) { 
    $this->config = $array; 
    } 

    public function __get($name) { 
    if(is_array($this->config[$name])) { 
     return new ConfigArray($this->config[$name]); 
    } else { 
     return $this->config[$name]; 
    } 
    } 
} 

這讓我我的鏈配置訪問。當我使用PHP 5.3時,讓ConfigArray擴展ArrayObject(在5.3中默認激活SPL)也是一個好主意。

任何建議,改進,意見?

+2

如果你真的想爲' - >'交換'[]',我會選擇一個裸露的ArrayObject,但是我不想那樣改變它。每次請求時創建一個_new_對象將是一個麻煩,但我會遞歸地走數組,並將數組修改爲arrayobjects只有一次。 – Wrikken 2010-09-15 21:28:41

+0

@Wrikken:確實,在真實的實現中會改變這種行爲。 – halfdan 2010-09-15 21:49:38

回答

1

如果$this->config數組的元素也是Config類的實例,那麼它可以工作。

Zend Framework有一個類似的組件,他們稱之爲Zend_Config。您可以download來源,並檢查他們如何實施它。他們不必一路去擴展ArrayObject

Zend_Registry類具有類似的用法,它的確擴展了ArrayObject。 Zend_Registry的代碼因此更簡單一些。

+0

看着Zend_Config :: __構造:他們爲更深的數組維度創建'new self($ value,..)'。 – halfdan 2010-09-15 21:39:40