2012-02-05 9 views
1

を実装する方法..私は以下のショーとして中央構成レジストリを使用するアプリケーション。..コンフィグレジストリ - 私はいくつかの入力/指導した後、午前

アプリケーションは、iniファイルのためのconfigディレクトリを解析し、配列を設定していインデックス、ならびに単一の構成変数必要に応じてファイルの名前を使用して、クラス..へ

私はいくつかの問題が生じるなど、見ることができます

:ファイル間

  1. 名前の衝突をし、内の設定VARSスクリプト
  2. ネストした配列変数をプルできないため、次のコードが生成されます。

    $ databases = config :: get( 'database'); $ actual_record = $ databases ['default'];

ネストされた値の2番目のgetパラメータを追加するように誘惑されましたが、3番目または4番目のレベルの値を引き出す必要がある場合はどうなりますか。

class config 
{ 
    private static $registry; 

    /** 
    * 
    */ 
    private function __construct() {} 

    /** 
    * 
    */ 
    public static function get($key) 
    { 
     if (isset(self::$registry[$key])) return self::$registry[$key]; 
     else return FALSE; 
    } 

    /** 
    * 
    */ 
    public static function set($key, $value, $overwrite = FALSE) 
    { 
     // Does the variable already exist? 
     if (isset(self::$registry[$key]) && $overwrite === FALSE) 
     throw new Exception(); 

     self::$registry[$key] = $value; 
    } 
} 

助けを事前に感謝しますが...

+0

値を再度取得するメソッドを持つオブジェクトに各エントリをカプセル化できます。 'config :: getNested( 'database') - > get( 'default')'です。それが可能であれば、入れ子にしないでください。それらをドットで分けるのはどうですか? 'config :: get( 'database.default')' – Dan

+0

これは愚かな質問かもしれませんが、database.default表記法をどのように配列呼び出しに変換しますか? – Lee

+0

識別子をトークン化し、ドットで分割します。ドットがない場合はプレーンコール、それ以外の場合は最初のパラメータの名前と最初のドットの後ろのパラメータで指定されたフィールドの配列をフィールドで取得します。アイデアが好きなら、私は答えにいくつかのコードを投稿することができます。 – Dan

答えて

1

コードですドットで区切られた名前を機能させる。より効率的なソリューションがあるかもしれません、私はちょうどあなたのために一緒にこれを投げた。

class Config 
{ 
    private 
     $registry 
    ; 

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

    public function get($identifier) 
    { 
     return $this->resolve(explode('.', $identifier), $this->registry); 
    } 

    private function resolve($entries, $in) 
    { 
     if(key_exists($entries[0], $in) && count($entries) > 1) 
     { 
      // We have more than one level to resolve 
      $newIn = $in[$entries[0]]; 
      unset($entries[0]); 
      return $this->resolve(array_values($entries), $newIn); 
     } 
     elseif(key_exists($entries[0], $in) && count($entries) == 1) 
     { 
      // We are at the bottom, let's return. 
      return $in[$entries[0]]; 
     } 
     // If we get here something went wrong. 
     throw new Exception('Entry could not be resolved.'); 
    } 
} 

$cfg = new Config(
    array(
     'plain' => 'plain entry', 
     'nested' => array(
      'first' => 'nested, first entry', 
      'second' => array(
       'third' => 'deeper nested entry' 
      ) 
     ) 
    ) 
); 

print_r($cfg->get('plain'))."\n"; 
print_r($cfg->get('nested.first'))."\n"; 
print_r($cfg->get('nested.second.third'))."\n"; 
2

私が正しくあなたを理解していれば、次のレベルに複数の値がある場合は、再びconfigの新しいインスタンスを追加することができます。

この

value.second = a 
value.third = b 
other.value.my = a 
other.value.foo = b 

、このようなクラスツリーにつながる(configのような構成では、常にクラスのインスタンスであるとintendationは何かが上記configインスタンスの属性の配列であることを意味し、テキスト=>の前にインデックス名があり、これにアクセスします)。

config 
    value => config 
     second => a 
     third => b 
    other => config 
     value => config 
      my => a 
      foo => b 

私はあなたが何を意味するかちょっと把握したいと思います。

次に、あなたがあなたの値にアクセスするには、次の方法のいずれかのArrayAccessまたはmagic methods__get__setのいずれかを実現することができます。ここのコメントで提案されているように

config->value->second 
config->other->value->my 

または

config['value']['second'] 
config['other']['value']['my'] 
関連する問題