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

jimmck's avatar

Uncomment the nesting level or turn off debugger. Depending on the xdebug build, the default is 100.

[XDebug]
zend_extension="/Applications/XAMPP/xamppfiles/lib/php/extensions/no-debug-non-zts-20131226/xdebug.so"
;xdebug.max_nesting_level = 100
xdebug.remote_enable=1
xdebug.remote_host=localhost
xdebug.remote_port=9000
xdebug.remote_autostart=1
xdebug.profiler_enable=0
xdebug.profiler_output_dir="/Users/jimm"
xdebug.idkey=PHPSTORM
opheliadesign's avatar

@jimmck where is the file? Is this supposed to be in php.ini? I've looked all over and I cannot find any reference to xdebug. I'm running laravel/homestead 0.2.7, which it says is the latest one. I have run vagrant provision.

opheliadesign's avatar

@jimmck am I supposed to do this on my local install of PHP even though the code is being run on a virtual box (Homestead)? If you could provide a little step by step it would be appreciated. I Googled around a bit and cannot find anything specific to Laravel/Homestead as it relates to this - at least not how to actually change it.

jimmck's avatar

This is in your php.ini do you have access on your Homestead box?

opheliadesign's avatar

@jimmck I lied, found it on another thread here. @crynobone Fineeeeeeeeee you were right. Problem went away. But I still don't like that something trivial like this is making more than 100 nested calls, but that's not an exclusive thing to Laravel.

Guys, know what the really funny part is here? I tried to push it to production to see what would happen there and I don't have a high enough PHP version on that server :P That's tomorrow's task.

Thanks for the help, everyone!

opheliadesign's avatar

@jimmck I added the line to /etc/php5/fpm/conf.d/20-xdebug.ini, there was only that one other line there.

Kryptonit3's avatar

How do your models look? I see you are eager loading with(['Camp', 'Children', 'ChildrenCount'])

Do the models that are eager loaded, eager load something as well? I had a case where I eager loaded a model that also eager loaded some models that eager loaded the original model and it was a cluster f*ck.

opheliadesign's avatar

@jimmck yes, it just runs CSS inline on a Blade template. But the problem remained even after I stripped all logic from the handler() method. And only from the controller.

opheliadesign's avatar

Also, another 5.1 project on the same box has much more complex event handlers/listeners and hasn't had this error.

opheliadesign's avatar

@Kryptonit3 indeed they do!

<?php namespace App;

use Illuminate\Database\Eloquent\Model;

class CampParent extends Model {

    protected $with = ['children'];
    protected $fillable = ['first_name', 'last_name', 'email', 'phone', 'token'];
    protected $casts = ['completed' => 'boolean', 'stripe_details' => 'json', 'stripe_args' => 'json'];

    public function camp()
    {
        return $this->belongsTo('App\Camp');
    }

    public function children()
    {
        return $this->hasMany('App\CampChild', 'camp_parent_id');
    }

    public function setFirstNameAttribute($firstName)
    {
        $this->attributes['first_name'] = trim(ucfirst($firstName));
    }

    public function setLastNameAttribute($lastName)
    {
        $this->attributes['last_name'] = trim(ucfirst($lastName));
    }

    public function setEmailAttribute($email) {
        $this->attributes['email'] = trim($email);
    }

    public function getPhoneAttribute($phoneNumber)
    {
        if ($phoneNumber) {
            $output = substr($phoneNumber, 0, 3) . '-' . substr($phoneNumber, 3, 3) . '-' . substr($phoneNumber, 6);

            return $output;
        }
    }
    
    public function childrenCount()
    {
        return $this->hasOne('App\CampChild')
            ->selectRaw('camp_parent_id, count(*) as aggregate')
            ->groupBy('camp_parent_id');
    }

    public function getChildrenCountAttribute()
    {
        // if relation is not loaded already, let's do it first
        if ( ! array_key_exists('childrenCount', $this->relations))
            $this->load('childrenCount');

        $related = $this->getRelation('childrenCount');

        // then return the count directly
        return ($related) ? (int) $related->aggregate : 0;
    }
}

<?php namespace App;

use Illuminate\Database\Eloquent\Model;

class CampChild extends Model {

    protected $fillable = ['camp_parent_id', 'camp_id', 'first_name', 'last_name', 'dob', 'shirt_size_id', 'token'];
    protected $with = ['shirtSize'];
    protected $dates = ['dob'];

    public function shirtSize()
    {
        return $this->belongsTo('App\ShirtSize');
    }

    public function setFirstNameAttribute($firstName)
    {
        $this->attributes['first_name'] = trim(ucfirst($firstName));
    }

    public function setLastNameAttribute($lastName)
    {
        $this->attributes['last_name'] = trim(ucfirst($lastName));
    }
}

jimmck's avatar

@opheliadesign Thank You sir! I have an interest from a design point of view. Its seems its always, Events, Mail the handling there in...

opheliadesign's avatar

@Kryptonit3 I'll check it out tomorrow (wife yelling at me to come to bed lol). So the eager loading from within the model could have caused all of this? Would firing the event from within the controller have just pushed it over the 100 limit, as @crynobone was suggesting?

1 like
Kryptonit3's avatar

No way to know without playing around. But the debug bar is a definite need in all projects and during development for me. I love seeing what queries are being called, and optimizing them.

1 like
opheliadesign's avatar

@Kryptonit3 sounds good, thanks again for all your help! That was enough frustration for one evening, off to bed I go.

Thanks again, everyone!

1 like
Kryptonit3's avatar

P.S. eager loading in models is fine. But when multiple models that are related, eager load each other at the same time, that is where you run into problems.

jimmck's avatar

@opheliadesign and @Kryptonit3 Here is the Stackframe from PHPStorm for a Simple Event being fired from a Controller.

<?php namespace App\Http\Controllers\nesting;

use App\Events\MyEvent;
use App\Http\Controllers\Controller;

class NestController extends Controller
{
    public function fire()
    {
        \Event::fire(new MyEvent("Hello Lissa..."));
        return "Fired...";
    }
}
<?php namespace App\Events;

class MyEvent extends \Event
{
    public  $event;
    /**
     * Create a new event instance.
     * @param $event
     */
    public function __construct($event)
    {
        $this->event = $event;
    }
}
<?php namespace App\Handlers\Events;

use App\Events\MyEvent;
use Monolog\Logger;

class MyEventHandler
{

    /**
     * Create the event handler.
     *
     *
     */
    public function __construct()
    {
        //
    }

    /**
     * Handle the event.
     *
     * @param  MyEvent $event
     *
     * @return void
     */
    public function handle(MyEvent $event)
    {
        //
        $d = $event;
    }
}

And the Event Service Listener:

<?php namespace App\Providers;

use App\Events\MyEvent;
use App\Handlers\Events\MyEventHandler;

use Illuminate\Contracts\Events\Dispatcher as DispatcherContract;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;

class EventServiceProvider extends ServiceProvider {

    /**
     * The event handler mappings for the application.
     *
     * @var array
     */
    protected $listen = [
        MyEvent::class => [
            MyEventHandler::class,
        ],
    ];

    /**
     * Register any other events for your application.
     *
     * @param  \Illuminate\Contracts\Events\Dispatcher  $events
     * @return void
     */
    public function boot(DispatcherContract $events)
    {
        parent::boot($events);

        //
    }

}

This should get an idea of how to read the stack frame. The highlighted line in the frame is the NestedController call.

jimmck's avatar

I am going to play around with Mailer and the listen array. @opheliadesign can you please post your EventServiceProvider listener array. Also what does each handler call? Do any overlap?

opheliadesign's avatar

@jimmck just one event and listener. No overlap.

protected $listen = [
        'App\Events\CampRegistrationWasPayed' => [
            'App\Listeners\SendCampPurchaseConfirmation'
        ],
    ];

@Kryptonit3 it is queued, yes - however, in development, I am using the sync driver because I had issues with beanstalkd getting stuck in infinite loops if there was an error.

So, really, unless I totally botched something during upgrade I'm not trying to do anything super complex here. I know everyone says that the maximum nested level error is not a bug but I can't stop feeling like something is just very wrong when these appear.

opheliadesign's avatar

Okay so this morning I reset the xdebug so that the error would occur again and drilled down through everything. If I do dd($content), which is the inlined HTML/CSS Blade template used for the mail, everything is fine. It poops the bed only if Mail is used.

In the other 5.1 project it just occurred to me that I'm using Mailgun's API directly in everything because I am using batch sending. So that's why I have not come across the Maximum nested level error before in that project. I HAD experienced this in 5.0 when attempting to send mail using Mail::send from within a command.

I'm sorry, disagree all you want, but to me this feels like a bug with Mail. Or just perhaps code that can be improved so there is not as much nesting? What are the 100+ functions that must be gone through just to send out mail?

opheliadesign's avatar

@jimmck @Kryptonit3 So, here is my listener with Mailgun in place of Mail, problem completely eliminted:

<?php

namespace App\Listeners;

use App\Events\CampRegistrationWasPayed;
use App\Library\InlineEmail;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Mailgun\Mailgun;

class SendCampPurchaseConfirmation implements ShouldQueue
{
    use InteractsWithQueue;

    private $mailgun;

    /**
     *
     */
    public function __construct()
    {
        $this->mailgun = new Mailgun("key-");
    }

    /**
     * Handle the event.
     *
     * @param  CampRegistrationWasPayed  $event
     * @return void
     */
    public function handle(CampRegistrationWasPayed $event)
    {
        $parent = $event->parent;

        $subject = "EYFA Football Camp Receipt - {$parent->camp->title}";
        $title = $parent->camp->title;
        $amount = number_format($parent->camp->price * $parent->childrenCount, 2);
        $campPrice = number_format($parent->camp->price, 2);
        $childrenCount = $parent->childrenCount;
        $card = $parent->stripe_args['card'];
        $token = $parent->token;
        $campers = $parent->children;
        $recipient = $parent->email;
        $name = "{$parent->first_name} {$parent->last_name}";

        $data = compact('subject', 'title', 'amount', 'campPrice', 'childrenCount', 'card', 'token', 'campers', 'recipient', 'name');

        $inliner = new InlineEmail('emails.camp.receipt', $data);
        $content = $inliner->convert();
         // Send the email
//        Mail::send('emails.raw', ['content' => $content], function ($message) use ($data) {
//            $message->from('support@demo.org', 'EYFA Website Support');
//            $message->to($data['recipient'], $data['name']);
//            $message->subject($data['subject']);
//        });
        $this->mailgun->sendMessage('demo.org', [
            'from' => 'support@demo.org',
            'to' => $data['recipient'],
            'subject' => $data['subject'],
            'html' => $content,
            'text' => 'EYFA Football Camp Receipt. Please view this email in a modern email client.'
        ]);
    }
}
jimmck's avatar

@opheliadesign Hey, sorry been away. Question, what happens when xdebug is off? Are you using PHPStorm. Also you are using the queue traits in your listener?

opheliadesign's avatar

@jimmck thanks for getting back to me :) If I set the maximum nesting level in xdebug to 250 the problem goes away while using Mail. However, if I don't use Mail in my Listener without messing with xdebug, there are no problems. I am indeed using PHPStorm

To answer your last question, I'm not sure - my listener is above.

jimmck's avatar

@opheliadesign But with debug off and use mail you get problems? PHP hangs or exhusts its process stack space? Only with mail gun?

opheliadesign's avatar

@jimmck to be honest I don't even know how to turn off xdebug. This is on a Homestead virtual machine, using whatever settings came with that. I don't know if PHP hangs or exhausts process stack space, I just know that Maximum Nested Level 100 gets thrown if I use Mail in the event.

jimmck's avatar

@opheliadesign Yes but, unless you are running with phpstorm in debug mode, xdebug should be off. Do remote into your homestead box? I run local servers and an AWS instance. Weird? When debug is off PHP blows up when I go to recursion heaven.

Please or to participate in this conversation.