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

Scooby's avatar

Laravel 11 register event with multiple listeners

Prior to Laravel 11 events could be manually registered with multiple listeners in the EventServiceProvider as follows (note: this does still work, but looking for the latest recommended approach):

protected $listen = [
    EventName::class => [
        FirstEventListener::class,
        SecondEventListener::class,
    ],
];

I'm currently migrating this over to the new Laravel 11 way to manually register events as per the documentation here:

https://laravel.com/docs/11.x/events#manually-registering-events

I'm not finding any way to register an event with multiple listeners other than the following:

Event::listen(
    EventName::class,
    FirstEventListener::class,
);

Event::listen(
    EventName::class,
    SecondEventListener::class,
);

Is this just how it is now or am I missing a way to do something similar to the following?

Event::listen(
    EventName::class,
    [
        FirstEventListener::class,
        SecondEventListener::class,
    ],
);
0 likes
10 replies
LaryAI's avatar
Level 58

In Laravel 11, you can still register multiple listeners for a single event, but the syntax is slightly different from what you've shown in your last code snippet. You can use the Event::listen method multiple times for the same event, as you've already discovered. However, if you want to register multiple listeners at once, you can use a loop or an array map. Here's an example of how you can do it:

foreach ([FirstEventListener::class, SecondEventListener::class] as $listener) {
    Event::listen(EventName::class, $listener);
}

Alternatively, you can use array_map to achieve the same result:

array_map(function ($listener) {
    Event::listen(EventName::class, $listener);
}, [FirstEventListener::class, SecondEventListener::class]);

Both of these methods will register each listener for the EventName::class event. This is essentially the same as calling Event::listen multiple times, but it's a bit cleaner, especially if you have a large number of listeners.

As of my knowledge cutoff date, there isn't a built-in method in Laravel 11 to pass an array of listeners directly to the Event::listen method as you've shown in your last code snippet. You would need to iterate over the listeners in some way, as shown above.

Snapey's avatar

have you tried passing an array?

public function boot(): void
{
    Event::listen(
        PodcastProcessed::class,
        [
			SendPodcastNotification::class, 
            UpdateHomepage::class
		],
    );
}
Scooby's avatar

@Snapey Yeah it ends up registering as follows:

App\Events\EventName .............................................................................................................
  ⇂ App\Listeners\FirstEventListener@App\Listeners\SecondEventListener

It seems that second array item is for if you needed to call a custom handler method:

Event::listen(EventName::class, [FirstEventListener::class, 'customHandler']);

Result:

App\Events\EventName .............................................................................................................
  ⇂ App\Listeners\FirstEventListener@customHandler
Snapey's avatar

@Scooby The old syntax would be;

public function boot(): void
{
    Event::listen(
        PodcastProcessed::class => [
			SendPodcastNotification::class, 
            UpdateHomepage::class
		]
    );
}

Maybe?

Or restore the old EventServiceProvider ?

Scooby's avatar

@Snapey Yeah restoring the old EventServiceProvider seemed to work but I just ran Shift on our application and it was a recommendation to migrate to the newer more modern Laravel setup.

Shift: Removing these files will keep your application modern and make future maintenance easier.

Scooby's avatar

@Snapey And also I tried the old syntax but it threw an error:

str_contains(): Argument #1 ($haystack) must be of type string, array given

Scooby's avatar

Well, I'm gonna assume there's no current built in way to accomplish this so I just resorted to creating a macro:

use Illuminate\Events\Dispatcher;
use Illuminate\Support\Facades\Event;

Dispatcher::macro('listeners', function ($events, array $listeners = []) {
    array_map(function ($listener) use ($events) {
        Event::listen($events, $listener);
    }, $listeners);
});

Just call this:

Event::listeners(EventName::class, [
    FirstEventListener::class,
    SecondEventListener::class,
]);

And then the result is this:

App\Events\EventName .............................................................................
  ⇂ App\Listeners\FirstEventListener
  ⇂ App\Listeners\SecondEventListener

Seems to work well enough.

1 like
Byorun's avatar

for listening to multiple events I just added (in my case 2) all the needed events to the type hint like this

public function handle(OmeStreamStarted|OmeStreamStopped $event): void
    {
        dump($event);
    }

in your handle method you can then do something like instanceof. This approach is probably not suitable for handling more than two or three events.

1 like
pomirleanu's avatar

In this case, I've moved all the events listeners to a folder called OldListeners, kept my old EventServiceProvider, and registered it in the providers.php.

Please or to participate in this conversation.