Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

dniccum's avatar

Two inter dependency repository classes causes memory leak

Within my Laravel application I have two repositories that are dependencies of each other, like so:

class QuizRepository extends BaseRepository implements QuizInterface
{
    /**
     * @var Quiz $model
     */
    protected $model;

    /**
     * @var CompletedQuizRepository $completedQuizRepository
     */
    private $completedQuizRepository;

    function __construct(Quiz $model, CompletedQuizRepository $completedQuizRepository)
    {
        $this->model = $model;
        $this->completedQuizRepository = $completedQuizRepository;
    }
}

and

class CompletedQuizRepository extends BaseRepository implements CompletedQuizInterface
{
    /**
     * @var CompletedQuiz $model
     */
    protected $model;

    /**
     * @var QuizRepository $quizRepository
     */
    private $quizRepository;

    function __construct(CompletedQuiz $model, QuizRepository $quizRepository)
    {
        $this->model = $model;
        $this->quizRepository = $quizRepository;
    }
}

When the application attempts to run, I get an error stating that the "maximum function nesting level has been exceeded" or the application is out of memory; in essence the application has a memory leak.

While I do want to implement best standard practices, but I also want my application to run as well. Is there something that I can do to avoid this problem?

0 likes
5 replies
rin4ik's avatar

Increase the value of xdebug.max_nesting_level in your php.ini for instance:

xdebug.max_nesting_level = 1000
dniccum's avatar

Unfortunately this does not work. I had tried this before, but then I started to receive errors that my application was running out of memory. I was granting my PHP processes access to 2 GB of RAM and it was still throwing 500 errors.

click's avatar

I think you've created an endless (circular) loop with dependency injection. A requires B and B requires A.

As soon as your CompletedQuizRepository class is initialized theQuizRepository is initialized because of the automatic dependency injection. As soon as QuizRepository is initialized it will create a new instance of CompletedQuizRepository but this instances requires a QuizRepository and this QuizRepository requires a CompletedQuizRepository and so on until your system stops working.

Increasing a max_nesting_level is never a good idea because there is most of the time something wrong with your code.

Without further insight in your code a solution would be to stop passing these instances in the constructor and create a getter and setter method for it.

martinbean's avatar
Level 80

@dniccum Yes, you have a circular dependency.

Your repositories shouldn’t really be interacting with each other. It’s the responsibility of client code to request the data it needs from multiple repositories, not for repositories themselves to be fetching data from other repositories.

Instead, create a service class that interacts with both repositories to fetch the data you need for a particular request.

However, if your “completed quiz” repository is filtering your base quiz repository to just completed quizzes only, then that should probably be a decorator of the quiz repository, that adds criteria to the base query.

3 likes

Please or to participate in this conversation.