Php Symfony依赖项注入:最大函数嵌套级别

Php Symfony依赖项注入:最大函数嵌套级别,php,symfony,testing,dependency-injection,Php,Symfony,Testing,Dependency Injection,我有一个基于symfony4的项目。我想开始基于WebTestCase编写功能测试。我在配置中启用了framework.test:true,并在phpunit中提供了APP_ENV=test 为测试环境构建的服务容器存在问题。除了APP_ENV和framework.test,我几乎没有改变任何东西 当我从测试缓存容器获取服务时,我最终得到: Maximum function nesting level of '256' reached, aborting! 在stack trace中,我可以看

我有一个基于symfony4的项目。我想开始基于
WebTestCase
编写功能测试。我在配置中启用了
framework.test:true
,并在phpunit中提供了
APP_ENV=test

为测试环境构建的服务容器存在问题。除了
APP_ENV
framework.test
,我几乎没有改变任何东西

当我从测试缓存容器获取服务时,我最终得到:

Maximum function nesting level of '256' reached, aborting!
在stack trace中,我可以看到symfony的DI一直在尝试获取相同的服务:

 ...
 ContainerE6ODQnH\srcApp_KernelTestDebugContainer->getPanel_Model_EventService() at /var/www/html/panel/var/cache/test/ContainerE6ODQnH/srcApp_KernelTestDebugContainer.php:483
 ContainerE6ODQnH\srcApp_KernelTestDebugContainer->getDefaultEventRepositoryService() at /var/www/html/panel/var/cache/test/ContainerE6ODQnH/srcApp_KernelTestDebugContainer.php:525
 ContainerE6ODQnH\srcApp_KernelTestDebugContainer->getDbReachingEventTranslationProviderService() at /var/www/html/panel/var/cache/test/ContainerE6ODQnH/srcApp_KernelTestDebugContainer.php:509
 ContainerE6ODQnH\srcApp_KernelTestDebugContainer->getCachingEventTranslationProviderService() at /var/www/html/panel/var/cache/test/ContainerE6ODQnH/srcApp_KernelTestDebugContainer.php:541
 ContainerE6ODQnH\srcApp_KernelTestDebugContainer->getEventContextTakingTranslatorService() at /var/www/html/panel/var/cache/test/ContainerE6ODQnH/srcApp_KernelTestDebugContainer.php:402
 ContainerE6ODQnH\srcApp_KernelTestDebugContainer->getModelConfiguratorService() at /var/www/html/panel/var/cache/test/ContainerE6ODQnH/srcApp_KernelTestDebugContainer.php:1089
 ContainerE6ODQnH\srcApp_KernelTestDebugContainer->getPanel_Model_EventService() at /var/www/html/panel/var/cache/test/ContainerE6ODQnH/srcApp_KernelTestDebugContainer.php:483
 ContainerE6ODQnH\srcApp_KernelTestDebugContainer->getDefaultEventRepositoryService() at /var/www/html/panel/var/cache/test/ContainerE6ODQnH/srcApp_KernelTestDebugContainer.php:525
 ContainerE6ODQnH\srcApp_KernelTestDebugContainer->getDbReachingEventTranslationProviderService() at /var/www/html/panel/var/cache/test/ContainerE6ODQnH/srcApp_KernelTestDebugContainer.php:509
 ContainerE6ODQnH\srcApp_KernelTestDebugContainer->getCachingEventTranslationProviderService() at /var/www/html/panel/var/cache/test/ContainerE6ODQnH/srcApp_KernelTestDebugContainer.php:541
 ContainerE6ODQnH\srcApp_KernelTestDebugContainer->getEventContextTakingTranslatorService() at /var/www/html/panel/var/cache/test/ContainerE6ODQnH/srcApp_KernelTestDebugContainer.php:402
 ContainerE6ODQnH\srcApp_KernelTestDebugContainer->getModelConfiguratorService() at /var/www/html/panel/var/cache/test/ContainerE6ODQnH/srcApp_KernelTestDebugContainer.php:1089
 ContainerE6ODQnH\srcApp_KernelTestDebugContainer->getPanel_Model_EventService() at /var/www/html/panel/var/cache/test/ContainerE6ODQnH/srcApp_KernelTestDebugContainer.php:483
 ContainerE6ODQnH\srcApp_KernelTestDebugContainer->getDefaultEventRepositoryService() at /var/www/html/panel/var/cache/test/ContainerE6ODQnH/srcApp_KernelTestDebugContainer.php:525
 ContainerE6ODQnH\srcApp_KernelTestDebugContainer->getDbReachingEventTranslationProviderService() at /var/www/html/panel/var/cache/test/ContainerE6ODQnH/srcApp_KernelTestDebugContainer.php:509
 ContainerE6ODQnH\srcApp_KernelTestDebugContainer->getCachingEventTranslationProviderService() at /var/www/html/panel/var/cache/test/ContainerE6ODQnH/srcApp_KernelTestDebugContainer.php:541
 ContainerE6ODQnH\srcApp_KernelTestDebugContainer->getEventContextTakingTranslatorService() at /var/www/html/panel/var/cache/test/ContainerE6ODQnH/srcApp_KernelTestDebugContainer.php:402
 ContainerE6ODQnH\srcApp_KernelTestDebugContainer->getModelConfiguratorService() at /var/www/html/panel/var/cache/test/ContainerE6ODQnH/srcApp_KernelTestDebugContainer.php:1089
 ContainerE6ODQnH\srcApp_KernelTestDebugContainer->getPanel_Model_EventService() at /var/www/html/panel/var/cache/test/ContainerE6ODQnH/srcApp_KernelTestDebugContainer.php:483
...
这很奇怪,因为我的定义中没有循环引用
APP\u ENV=dev中
一切正常。

看起来由于某种原因,
test
容器无法记住对
$this->services
属性中现有服务的引用

您知道dev和测试容器的构建差异吗

当我比较测试容器php文件和开发版本时。它们确实不同。没有理由

更新

以下是调用循环中生成的服务的示例:

DEV

    protected function getDefaultEventRepositoryService()
    {
        $a = \ClassRegistry::init('Event');

        $this->services['Panel\\Events\\Repository\\DefaultEventRepository'] = $instance = new \Panel\Events\Repository\DefaultEventRepository($a, ($this->services['Panel\\Events\\Repository\\EventMapper'] ?? ($this->services['Panel\\Events\\Repository\\EventMapper'] = new \Panel\Events\Repository\EventMapper())), ($this->privates['timeProvider'] ?? ($this->privates['timeProvider'] = new \Panel\Core\Utils\CurrentTimeProvider())));

        ($this->services['CakeFramework\\ModelConfigurator'] ?? $this->getModelConfiguratorService())->configure($a);

        return $instance;
    }
测试

    protected function getDefaultEventRepositoryService()
    {
        $a = $this->getPanel_Model_EventService();

        if (isset($this->services['Panel\\Events\\Repository\\DefaultEventRepository'])) {
            return $this->services['Panel\\Events\\Repository\\DefaultEventRepository'];
        }

        return $this->services['Panel\\Events\\Repository\\DefaultEventRepository'] = new \Panel\Events\Repository\DefaultEventRepository($a, ($this->services['Panel\\Events\\Repository\\EventMapper'] ?? ($this->services['Panel\\Events\\Repository\\EventMapper'] = new \Panel\Events\Repository\EventMapper())), ($this->privates['timeProvider'] ?? ($this->privates['timeProvider'] = new \Panel\Core\Utils\CurrentTimeProvider())));
    }
正如你在上面所看到的,两者略有不同。测试环境正在使用服务方法
getPanel\u Model\u EventService
。但在开发环境中,它被直接注入
$a=\ClassRegistry::init('Event')


尽管服务定义相同,但这会导致循环引用。没有附加的
服务测试
文件。知道为什么吗?

我调查了这个问题。这是由Symfony的配置器机制和缺乏报告循环依赖性造成的

我在public repo中用代码示例描述了这个问题:

切换到工厂有助于发现确实存在循环依赖。使用工厂加薪:

PHP Fatal error:  Uncaught Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException: Circular reference detected for service ...

我调查了这个问题。这是由Symfony的配置器机制和缺乏报告循环依赖性造成的

我在public repo中用代码示例描述了这个问题:

切换到工厂有助于发现确实存在循环依赖。使用工厂加薪:

PHP Fatal error:  Uncaught Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException: Circular reference detected for service ...

您是否尝试在php.ini中提升
xdebug.max\u nesting\u level=1024
?这肯定是循环引用吗?是的,我提高了这个限制。结果是一样的。我用循环调用循环生成服务的示例更新了文章。正如您所看到的,它略有不同。您是否尝试在php.ini中提升
xdebug.max\u nesting\u level=1024
?这肯定是循环引用吗?是的,我提高了这个限制。结果是一样的。我用循环调用循环生成服务的示例更新了文章。正如你所看到的,这有点不同。