Question

I'm working on a reasonably large Laravel project and am using Repositories.

I have a user repository which injects its dependencies like so:

public function __construct(CartRepository $cartRepo...)

This causes the following error:

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

I think this is because the CartRepo injects an ItemRepo which in turn injects the UserRepo, causing an infinite nesting loop.

What I don't get is how to find away around this, the ItemRepo needs the UserRepo as items are tied to a user?

Has anyone come across this before? If so how'd you get around it?

I know I can increase xdebug.max_nesting_level but even with a value of 750 it's still throwing an error, I'd also rather fix the underlying problem than just bury it.

Was it helpful?

Solution

You have a cycle in your dependency graph:

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

You can't resolve that. It's an infinite loop, xdebug.max_nesting_level won't help you.

I'm just surprised that Laravel DI container doesn't throw an explicit exception.

You have to rethink your dependencies between services/repositories, maybe by splitting some classes into smaller, less coupled objects.


Update: Woops, I forgot about a couple of solutions!

  • Setter injection

Rather than injecting a dependency in the constructor, you can have it injected in a setter, which would be called after the object is constructed. In pseudo-code, that would look like that:

$userRepo = new UserRepository();
$cartRepo = new CartRepository($userRepo);
$userRepo->setCartRepo($userRepo);
  • Lazy injection

I don't know if Laravel does support lazy injection, but that's also a solution: the container will inject a proxy object instead of the actual dependency. That proxy-object will load the dependency only when it is accessed, thus removing the need to build the dependency when the constructor is called.

OTHER TIPS

For those who reach this answer and still are a little unsure of what to do like myself, I just wanted to share my solution. Matthieu's solution is correct but for a beginner like myself it still didn't give me a concrete answer to actually solving cyclical dependency. In the end I came to the conclusion that my classes were too large and that breaking them up into smaller classes even classes with just one method was the answer. For example if you have a User class that contains a login method and registration method and then a some other class, say a Social Class that uses the login method of the user class and for whatever reason the User class has a dependency on the Social class then my solution would be to move the login method into its own class which wouldn't have any dependencies. This way the Social class now uses the Login class, which doesn't have any dependencies. Overall I went from about 3 classes to 9 and this completely solved the issue for me. I think this type of thinking is intuitive for non-beginners but if you don't know what you don't know, it can be tough.

The cause of your error could be a bug on Laravel, but i'm currently working with symfony2, and symfony2 did the same thing (on entity classes for example) without problems. Whatever set your php.ini setting max_nesting_level (64 by default) to higher value, or if you're using xdebug check xdebug.max_nesting_level setting. Try the last suggestion first...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top