自引用模型会导致Laravel 4中x的最大函数嵌套级别

时间:2013-11-11 14:48:57

标签: php laravel dependency-injection laravel-4 circular-dependency

我正在开发一个相当大的Laravel项目并使用Repositories。

我有一个用户存储库,它会像这样注入依赖项:

public function __construct(CartRepository $cartRepo...)

这会导致以下错误:

Maximum function nesting level of '100' reached, aborting!

我认为这是因为CartRepo注入一个ItemRepo,然后注入UserRepo,导致无限的嵌套循环。

我没有得到的是如何找到它,ItemRepo需要UserRepo,因为项目与用户绑定?

有没有人遇到过这个?如果是这样你怎么解决它?

我知道我可以增加xdebug.max_nesting_level,但即使值为750,它仍然会抛出错误,我也宁愿修复潜在的问题,而不仅仅是埋葬它。

3 个答案:

答案 0 :(得分:5)

您的依赖关系图中有一个循环:

UserRepo -> CartRepo -> ItemRepo -> UserRepo -> …

你无法解决这个问题。这是一个无限循环,xdebug.max_nesting_level对你没有帮助。

我很惊讶Laravel DI容器没有抛出显式异常。

您必须重新考虑服务/存储库之间的依赖关系,可能是将某些类拆分为较小的,耦合较少的对象。


更新:Woops,我忘记了几个解决方案!

  • Setter injection

不是在构造函数中注入依赖项,而是可以将它注入setter中,该setter将在构造对象后调用。在伪代码中,看起来像这样:

$userRepo = new UserRepository();
$cartRepo = new CartRepository($userRepo);
$userRepo->setCartRepo($userRepo);
  • 懒惰注射

我不知道Laravel是否支持延迟注入,但这也是一个解决方案:容器将注入代理对象而不是实际依赖。该proxy-object仅在访问时才加载依赖项,因此在调用构造函数时无需构建依赖项。

答案 1 :(得分:0)

对于那些达到这个答案并仍然不确定自己该怎么做的人,我只是想分享我的解决方案。 Matthieu的解决方案是正确的,但对于像我这样的初学者来说,它仍然没有给我一个实际解决周期性依赖的具体答案。最后我得出的结论是,我的课程太大了,而且只用一种方法将它们分成更小的类甚至类就是答案。例如,如果你有一个包含登录方法和注册方法的User类,然后是一个其他类,那么说一个使用用户类登录方法的社交类,无论出于何种原因,User类都依赖于Social类。那么我的解决方案是将登录方法移动到自己的类中,该类不具有任何依赖性。这样社交类现在使用Login类,它没有任何依赖项。总的来说,我从大约3班增加到9班,这完全解决了我的问题。我认为这种思维方式对于非初学者来说是直观的,但如果你不知道自己不知道什么,那就很难了。

答案 2 :(得分:-2)

您的错误原因可能是Laravel上的错误,但我目前正在使用symfony2,并且symfony2做了同样的事情(例如在实体类上)没有问题。无论如何将php.ini设置为max_nesting_level(默认为64)设置为更高的值,或者如果您正在使用xdebug检查xdebug.max_nesting_level设置。首先尝试最后的建议......