2016-04-06 1 views
1

Я определил два класса (Environment and ConfigurationReader). Оба они зарегистрированы как общие зависимости.Максимальная рекурсия, получающая общую услугу

Класс среды пытается получить текущую среду, но для этого необходимо прочитать конфигурационный файл через ConfigurationReader.

Диаграмма последовательности:

enter image description here

Классы:

class Environment 
{ 
    ... 
    public function resolve() 
    { 
     $config = DI::getDefault()->getCfg(); 
     $config->getValue('pepe', 'db_name'); 
    } 
    ... 
} 

class ConfigurationReader 
{ 
    ... 
    public function getValue($aConfig, $aKey) 
    { 
     $path = $this->getFile($aConfig); 
    } 

    protected function getFile($aConfig) 
    { 
     $env = DI::getDefault()->getEnv(); 
     $path = 'config/' . $env->getShortName() . '/' . $aConfig . '.yml'; 
     return $path; 
    } 
    ... 
} 

И регистрируются и созданы в index.php:

... 
$di = new FactoryDefault(); 
$di->setShared('env', function() use ($di) { 
    $env = new Services\Environment($di); 
    $env->resolve(); 
    return $env; 
}); 

$di->setShared('cfg', function() use ($di) { 
    return new Services\ConfigurationReader($di); 
}); 

$di->getShared('cfg'); 
$di->getShared('env'); 
... 

Итак, PHP авария на $config = DI::getDefault()->getCfg(); и говорит:

PHP Fatal error: Maximum recursion depth exceeded

Любые идеи?

+1

Вы передаете $ di в свой класс ConfigurationReader, что вы делаете с ним в своем конструкторе? –

ответ

3

Пара отмечает

  • Вы проходящее ди конструктору, но в конечном итоге получить его статически (DI :: getDefault())

  • относительно бесконечного цикла, это потому, что CFG нужен окр, кто нуждается в CFG, кто нуждается в окр и т.д .....

Чтобы иметь структуру автоматически впрыск DI в вашу службу, вы должны либо осуществить InjectionAwareInterfa ce (https://docs.phalconphp.com/en/latest/reference/di.html#automatic-injecting-of-the-di-itself) или расширяют класс Component (если вам нужно управление событиями, используйте плагин вместо Component). Посмотрите на эту дискуссию: https://forum.phalconphp.com/discussion/383/plugin-vs-component-what-s-the-difference-

Что касается вашего случая использования, не дают достаточно контекста для исчерпывающего ответа, но я думаю, что вы могли бы упростить как:

  • ConfigService: Если вы не используете config из разных env namespaces, вы должны передать значение $ env-> getShortName() в конструктор службы (не получая его из службы env). В наших приложениях env определяется nginx на основе имени домена или других параметров и передается как переменная среды в php. Кроме того, если у вас нет сотен конфигурационных файлов, и ваше приложение сильно зависит от них, вы должны прочитать и разобрать их один раз при создании экземпляра и сохранить конфиги в сервисе (как ассоциативный массив, объекты конфигурации или все, что вы предпочитаете) , Добавьте некоторый уровень кеша, чтобы не тратить ресурсы на разбор всех ваших файлов по каждому запросу. Фалконы предоставляют компонент Config для этого. Он поставляется с файловыми адаптерами (только формат ini и ассоциативного массива, но вы можете легко реализовать свой собственный yml-адаптер). Если большинство настроек вашего приложения зависят от настраиваемых значений, это, вероятно, будет первым компонентом, который вы хотите создать (или, по крайней мере, объявить в di). Он не должен зависеть от других сервисов.

  • EnvService: вы можете получить доступ к своим значениям конфигурации, вызвав службу конфигурации. Если у вас есть возможность расширить компонент, вы можете сделать что-то вроде $ this-> cfg-> getValue ($ key)).

+1

Люди, которые задают вопросы Phalcon, похоже, сосут в закрытии цикла обратной связи для тех, кто их отвечает. Хорошо продуманный и письменный ответ! –

+1

@JesseQ Yep тоже заметил, что это слишком плохо, потому что phalcon - это потрясающая структура ... – peuh