Php 配置注册表-如何实现

Php 配置注册表-如何实现,php,oop,object,static,config,Php,Oop,Object,Static,Config,我需要一些意见/指导。。我有一个使用中央配置注册表的应用程序,如下所示 应用程序解析ini文件的配置目录,并使用文件名作为索引将数组设置到类中,以及在需要时设置单个配置变量 我可以看到出现了一些问题,包括: 脚本中设置的文件和变量之间的名称冲突 无法提取嵌套数组变量,导致以下代码: $databases=config::get('database'); $actual_record=$databases['default'] 我很想为嵌套值添加第二个get参数,但是如果需要拉取第三或第四级值,将

我需要一些意见/指导。。我有一个使用中央配置注册表的应用程序,如下所示

应用程序解析ini文件的配置目录,并使用文件名作为索引将数组设置到类中,以及在需要时设置单个配置变量

我可以看到出现了一些问题,包括:

  • 脚本中设置的文件和变量之间的名称冲突
  • 无法提取嵌套数组变量,导致以下代码:

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

  • 我很想为嵌套值添加第二个get参数,但是如果需要拉取第三或第四级值,将来会发生什么

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

    提前感谢您的帮助。

    如果我理解正确,您可以再次添加
    config
    的新实例(如果下一级别有多个值)

    像这样的配置

    value.second = a
    value.third = b
    other.value.my = a
    other.value.foo = b
    
    然后会产生这样的类树(
    config
    始终是类的一个实例,而intendation意味着上面的
    config
    实例的属性数组中存在某些内容;
    =>
    前面的文本是索引名,您可以使用它们进行访问)

    我希望你能理解我的意思

    然后,您可以为以下方法之一实现或
    \uuuu get
    \uu set
    ,以访问您的值:

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


    正如在这里的注释中所建议的,是使点分隔名称起作用的代码。也许有一个更有效的解决方案,我只是为你准备了这个

    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";
    

    您可以将每个条目封装到一个对象中,该对象具有再次检索值的方法<代码>配置::getNested('database')->get('default')。或者,如果可能的话,不筑巢怎么样?用点把它们分开怎么样
    config::get('database.default')
    这可能是一个愚蠢的问题,但如何将database.default表示法转换为数组调用?标记标识符并在点处拆分它。如果没有点,这是一个普通调用,否则在第一个点后面的字段和参数指定的字段处获取数组,依此类推。如果你喜欢这个主意,我可以在回答中发布一些代码。谢谢Dan,是的,我喜欢这个主意。。一个编码示例将非常棒。。
    config['value']['second']
    config['other']['value']['my']
    
    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";