Skip to main content

Working with Laravel events

ยท 5 min read
Christophe
Markdown, WSL and Docker lover ~ PHP developer ~ Insatiable curious.

Working with Laravel events

When I started developing for the Joomla CMS (that 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, ... i.e. 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 interact with this event. You can add dynamic content, you can also deny the article to be displayed if certain conditions are not met.

When A user has registered is thrown, you can do a lot of things like welcoming this person, adding him to a distribution list, send him an email, ... but above all, and this is the most important for me, leave the door open to other actions that you don't yet know about.

For a web developer, a best approach, I think is to generate events even if it's your own code and you know what to do.

In fact, you never know

You don't 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 terribly easy for anyone to add a code "OK, when a new user registers, I need to ..."; something you didn't know then. Events are ideal for simplifying the addition of new functionalities.

Laravel exampleโ€‹

The example below is for the Laravel framework.

You need to run an event having one or more listeners and, in your main code, you wish to retrieve some values once listeners have done their job.

In our example below, we'll fire a SampleEvent class and his SampleListener. The idea is to initialize an employee.

File app/Providers/EventServiceProvider.php

protected $listen = [
SampleEvent::class => [
SampleListener::class,
],
];

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

use App\Employee;
use App\Events\SampleEvent;

Route::get('/', function () {
$employee = new Employee();

SampleEvent::dispatch($employee);

echo 'FIRSTNAME is ' . $employee->getFirstName() . PHP_EOL;
echo 'NAME is ' . $employee->getLastName() . PHP_EOL;
echo 'PSEUDO is ' . $employee->getPseudo() . PHP_EOL;
});

What we do is:

  1. Create a new employee based on the Employee class,
  2. Call our SampleEvent event and give our new employee,
  3. Let the magic happens,
  4. Display the employee's first and last name.

Here, by default, our employee.

File app/Employee.phpโ€‹

This class will initialize our employee and provide setters and getters.

By default, our employee will be called John Doe (cavo789).

<?php

namespace App;

class Employee
{
public function __construct(
private string $firstname = 'John',
private string $lastname = 'Doe',
private string $pseudo = 'cavo789'
) {
}

public function getFirstName(): string
{
return $this->firstname;
}

public function setFirstName(string $firstname)
{
$this->firstname = $firstname;
return $this;
}

public function getLastName(): string
{
return $this->lastname;
}

public function setLastName(string $lastname)
{
$this->lastname = $lastname;
return $this;
}

public function getPseudo(): string
{
return $this->pseudo;
}

public function setPseudo(string $pseudo)
{
$this->pseudo = $pseudo;
return $this;
}
};

File app/Events/SampleEvent.phpโ€‹

Our event will receive an employee and make it private.

Make three setters public to allow listeners to update the first and the last name. Also allow initializing the pseudo.

<?php

namespace App\Events;

use App\Employee;
use Illuminate\Foundation\Events\Dispatchable;

class SampleEvent
{
use Dispatchable;

public function __construct(private Employee $employee)
{
}

public function setFirstName(string $firstname): self
{
$this->employee->setFirstName($firstname);
return $this;
}

public function setLastName(string $lastname): self
{
$this->employee->setLastName($lastname);
return $this;
}

public function setPseudo(string $pseudo): self
{
$this->employee->setPseudo($pseudo);
return $this;
}
}

File app/Listeners/SampleListener.phpโ€‹

Our listener logic. SampleListener will receive the SampleEvent as parameter and, thus, has access to all his public methods. We'll here update the first and the lastname, we'll 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');
}
}

The resultโ€‹

If we run curl localhost in the console, we'll get the output below showing us it has worked perfectly as expected.

FIRSTNAME is Georges
NAME is Washington
PSEUDO is cavo789

If we edit back the app/Providers/EventServiceProvider.php file and comment the listener like below illustrated, our code will still work.

protected $listen = [
SampleEvent::class => [
// SampleListener::class,
],
];
FIRSTNAME is John
NAME is Doe
PSEUDO is cavo789

PHP example (not Laravel)โ€‹

Years ago, I've written an example in pure PHP (not Laravel) and using the League\Event library as you can retrieve on https://event.thephpleague.com/.

The repository and sample code are on Github: https://github.com/cavo789/event_thephpleague_learning.

note

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