Make event registration in Laravel more readable

Let's move tons of code from EventServiceProvider

If you have ever registered events in Laravel, you most likely have an EventServiceProvider like on this image:

Listen property in EventServiceProvider is too long

Over time, the $listen property can grow to hundreds of lines and it will become more difficult to read the code 😵

I suggest you make a new type of classes in your application that I call "event registers". After you do this, your EventServiceProvider will look like this:

As you can see, there is a new property $registers, where you can put any count of event registers.

Is it better to read and maintain? Offcourse it is! 😎

Step 1. Create EventRegisters folder

A good way to store these classes is to make a new EventRegisters folder in your Providers folder.

Step 2. Create abstract class

Create a new file AbstractEventRegister.php inside this folder and insert the following code inside it:

1 2 3 4 5 6 7 8 9 10 11 12 13
<?php   namespace App\Providers\EventRegisters;   abstract class AbstractEventRegister { protected $listen = [];   public function listens(): array { return $this->listen; } }

Step 3. Create event registers

Now you can create as many event registration classes as you need. These classes must extends AbstractEventRegister and have the protected $listen property, like in EventServiceProvider.

For example, let's create a new event register class for registering events related to the Post model:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
<?php   namespace App\Providers\EventRegisters;   use App\Events\Post\PostCreated; use App\Events\Post\PostDeleted; use App\Events\Post\PostUpdated; use App\Listeners\Post\SendPostCreatedNotification; use App\Listeners\Post\SendPostDeletedNotification; use App\Listeners\Post\SendPostUpdatedNotification;   class PostEvents extends AbstractEventRegister { /** * The event listener mappings for the application. * * @var array */ protected $listen = [ PostCreated::class => [ SendPostCreatedNotification::class, ], PostUpdated::class => [ SendPostUpdatedNotification::class, ], PostDeleted::class => [ SendPostDeletedNotification::class, ], ]; }

Step 4. Create a trait for EventServiceProvider

In my application I store traits for providers in /app/Traits/Providers folder, but you can choose any other place if you want.

Create a new file EventRegistration.php and put this code inside:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
<?php   namespace App\Traits\Providers;   use App\Contracts\Providers\EventRegister; use Event;   trait EventRegistration { /** * Get event registers. * * @return array */ public function registers() { return $this->registers ?? []; }   /** * Register events and listeners. * * @return void */ public function registerEvents() { $eventRegisters = $this->registers();   if (!$eventRegisters) { return; }   foreach ($eventRegisters as $eventRegisterClass) { /** @var EventRegister $eventRegister */ $eventRegister = new $eventRegisterClass();   if (!$events = $eventRegister->listens()) { continue; }   foreach ($events as $event => $listeners) { foreach (array_unique($listeners) as $listener) { Event::listen($event, $listener); } } } } }

Step 5. Let the EventServiceProvider know about our event registers

Load your trait by using use statement at the beginning of the EventServiceProver class. After this you have to add $this->registerEvents(); to the boot method.

After all these manipulations, your EventServiceProvider will look like this:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
<?php   namespace App\Providers;   use App\Providers\EventRegisters\PostEvents; use App\Traits\Providers\EventRegistration; use Illuminate\Auth\Events\Registered; use Illuminate\Auth\Listeners\SendEmailVerificationNotification; use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;   class EventServiceProvider extends ServiceProvider { use EventRegistration;   /** * The event listener mappings for the application. * * @var array */ protected $listen = [ Registered::class => [ SendEmailVerificationNotification::class, ], ];   /** * Event registers. * * @var array * @link https://sarvarov.dev/laravel/better-event-registration.html */ protected $registers = [ PostEvents::class,   /* Put here your event registers */ ];   /** * Register any events for your application. * * @return void */ public function boot() { parent::boot();   $this->registerEvents(); } }

If you need to register some groups of events, all you need is create a new EventRegister class and load it inside protected $registers proterty of EventServiceProvider. That's all! ☺

Comments

Spelling error report

The following text will be sent to our editors: