Я после некоторого ввода/руководства. У меня есть приложение, которое использует центральный реестр конфигурации, как показано ниже..
Приложение анализирует каталог конфигурации на наличие файлов ini и устанавливает массивы в класс, используя имя файла в качестве индекса, а также, при необходимости, отдельные переменные конфигурации.
Я вижу несколько возникающих проблем, в том числе:
- Конфликты имен между файлами и переменными, установленными в скрипте
Невозможность извлечения вложенных переменных массива приводит к следующему коду:
$databases = config::get('база данных'); $actual_record = $базы данных['по умолчанию'];
У меня возник соблазн добавить второй параметр 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;
}
}
Заранее спасибо за помощь..
Ответ 1 · рейтинг 1 · Dan
Как предложено в комментариях, вот код, позволяющий работать с именами, разделенными точками. Может быть более эффективное решение, я просто собрал это для вас.
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 · рейтинг 2 · aufziehvogel
Если я вас правильно понял, вы можете снова добавить новый экземпляр config, если на следующем уровне есть несколько значений.
Такая конфигурация
value.second = a
value.third = b
other.value.my = a
other.value.foo = b
Это приведет к такому дереву классов (config всегда является экземпляром класса, и намерение означает, что что-то находится в массиве атрибутов экземпляра config выше; тексты перед => являются именами индексов, с которыми вы получите к ним доступ).
config
value => config
second => a
third => b
other => config
value => config
my => a
foo => b
Надеюсь, вы немного поняли, что я имею в виду.
Затем вы можете реализовать либо ArrayAccess, либо магические методы __get и __set для одного из следующих методы доступа к вашим значениям:
config->value->second
config->other->value->my
or
config['value']['second']
config['other']['value']['my']