Skip to main content

Working with Laravel events

Explore the power of Laravel events for clean, decoupled code. This guide provides a practical, step-by-step example of creating and dispatching an event with a listener.

· 5 min read
View raw
Christophe
Markdown, WSL and Docker lover ~ Insatiable curious.
Cet article existe aussi en français — lire la version française.

Changelog

Latest
Removed link to cavo789/event_thephpleague_learning (GitHub repository no longer exists).

Working with Laravel events

⚡
TL;DR

This article shows how to use Laravel's event/listener system to keep code decoupled: a SampleEvent carries an Employee object, a SampleListener (registered in EventServiceProvider) reacts to it and updates the employee's name, and removing the listener still leaves the base flow working — illustrating how events let future functionality hook into existing code without modifying it. A non-Laravel PHP example using League\Event is also referenced.

When I started developing for the Joomla CMS (which was 15 years ago, in 2009), one of the things I liked most was the notion of events.

For example An article is about to be posted, An article has been posted, A user has registered, these are actions that are announced by the CMS and to which you can react.

When An article is about to be displayed is generated, you can have one (or more) pieces of code that interact with this event. You can add dynamic content, you can also prevent the article from being displayed if certain conditions are not met.

What an event actually buys you​

Here is a Laravel route that creates an employee and displays their name. A listener is plugged on the event it fires:

>user@machine: ~/yourproject

Now the very same route, with that listener commented out. Same URL, same calling code, not a line changed in the controller:

>user@machine: ~/yourproject

The employee is back to their default name, and nothing crashed. That's the entire promise of events: a feature can be added or removed without the code that fires the event knowing about it.

Why it works​

  1. The route creates a new employee based on the Employee class, then fires a SampleEvent carrying that object.
  2. Any registered listener receives the event, and through it, the very same employee object; it can modify it.
  3. The route then displays the employee's first and last name, without ever knowing whether a listener did something or not.

In fact, you never know

You never know because your software will have a life of its own, because over the years other features will be added and other developers will modify it. If you're working with events, it will be very easy for anyone to add code like "OK, when a new user registers, I need to..."; something you didn't know then. Events are ideal for simplifying the addition of new functionality.

Building it​

Four small files and one line of wiring. Let's follow the flow, starting with the entry point.

For our example, your routes/web.php can look like this:

This class will initialize our employee and provide a setter and a getter. By default, our employee will be called John Doe (cavo789).

Our event will receive an employee and store it as a private property:

Our listener logic. SampleListener will receive the SampleEvent as a parameter and, thus, has access to all its public methods. We will here update the first and the last name, we will not update the pseudo:

<?php
namespace App\Listeners;
use App\Events\SampleEvent;
class SampleListener
{
public function handle(SampleEvent $event): void
{
$event->setFirstName('Georges')->setLastName('Washington');
}
}

This is a listener class that responds to SampleEvent events. When the event fires, it automatically sets the first and last name properties on that event object using method chaining.

And finally the wiring, i.e. the file that tells Laravel which listener answers which event:

To reproduce the second terminal shown at the top of this article, comment the listener in that file:

Under the Hood (skip this if you just want to use it)​

The three setters of the event are public on purpose: that's the only reason a listener, which lives in a totally different file, is allowed to update the first and the last name.

The pseudo, on the other hand, is only initialized and never updated by the listener; it's the part of the object that stays under the control of the code that fired the event. Deciding what a listener may and may not touch is exactly the design work an event class asks from you.

The same idea outside Laravel​

Events are not a Laravel invention. In plain PHP, the League\Event library (https://event.thephpleague.com/) gives you the same dispatcher/listener pair, with no framework attached.

Conclusion​

The whole point is in the two terminal outputs at the top: a feature was removed and the calling code didn't notice. Write events even in your own code, even when you're sure you know what to do with them, because in two years, someone (probably you) will want to hook something in.

Events are, by nature, invisible: they fire somewhere and something happens elsewhere. Laravel Telescope makes them visible again, which is a real help when debugging a decoupled application like this one.

Note

This is, partially, a copy of an article I have previously posted on https://dev.to/cavo789/working-with-laravel-events-2i6m


Was this article helpful?
Did you try the steps in this article?