Introduction to Laravel Events and Listeners for Clean Code
Learn how to use Laravel events and listeners to decouple secondary side effects from your primary business logic, resulting in cleaner, maintainable code.
Previously in this course, we explored Service-Oriented Task Management to keep our controllers lean. Today, we take that modularity a step further by learning how to handle secondary side effects using events and listeners.
When you build a feature—like creating a new task on our project board—you often need to perform actions that aren't core to that task's success. You might need to send a notification, clear a cache, or log an audit entry. If you pack all that into your TaskService, your code quickly becomes a "god object" that knows too much.
The Power of Decoupling
Laravel's event system allows you to separate the intent (the user created a task) from the reactions (what happens next). By using events, your TaskService simply shouts, "A task was created!" and doesn't care who—or what—is listening. This decoupling makes your system easier to test and extend.
Defining a Custom Event
An event is a simple class that acts as a data carrier. It holds the information necessary for your listeners to do their work.
Run this command to create an event:
php artisan make:event TaskCreated
Inside app/Events/TaskCreated.php, you'll define the properties:
PHPnamespace App\Events; use App\Models\Task; use Illuminate\Foundation\Events\Dispatchable; use Illuminate\Queue\SerializesModels; class TaskCreated { use Dispatchable, SerializesModels; public function __construct(public Task $task) { #6A9955">// } }
Implementing Listeners
A listener is a class that executes code when a specific event is fired. Let's create a listener that logs the task creation.
php artisan make:listener SendTaskNotification --event=TaskCreated
Inside app/Listeners/SendTaskNotification.php, the handle method receives the event instance:
PHPnamespace App\Listeners; use App\Events\TaskCreated; use Illuminate\Support\Facades\Log; class SendTaskNotification { public function handle(TaskCreated $event): void { Log::info("New task created: {$event->task->title}"); } }
Registering in EventServiceProvider
Laravel needs to know which listeners belong to which events. You register these in app/Providers/EventServiceProvider.php:
PHPprotected $listen = [ TaskCreated::class => [ SendTaskNotification::class, ], ];
Now, update your TaskService to fire the event:
PHPuse App\Events\TaskCreated; public function createTask(array $data) { $task = Task::create($data); #6A9955">// Dispatch the event event(new TaskCreated($task)); return $task; }
Hands-on Exercise
- Create a second listener,
ClearProjectCache, that logs "Clearing project cache" whenTaskCreatedfires. - Register it in your
EventServiceProvideralongside the existing notification listener. - Trigger the creation of a task via your API and check your
storage/logs/laravel.logto confirm both listeners executed.
Common Pitfalls
- Over-engineering: Don't turn every single method call into an event. Use them for side effects—things that aren't strictly required to return a successful response to the user.
- Dependency Bloat: If a listener needs to know about the entire world, rethink your architecture. A listener should focus on one responsibility.
- Silent Failures: If a listener throws an exception, it can stop the entire request cycle. Ensure your listeners have their own
try-catchblocks if they perform risky operations.
Recap
By mastering events and listeners, you've gained a powerful tool for decoupling your application logic. You've moved from tightly coupled, procedural code to a reactive architecture where components communicate through shared events. This keeps your services focused and your codebase clean.
Up next: We will discuss how to move these potentially slow side effects into the background using Asynchronous Processing with Queues.
Work with me

Laravel REST API Development
Clean, secure, well-documented Laravel REST APIs — the backend engine for your app, mobile client, or SaaS. Built by an API specialist.

FilamentPHP Admin Panel & Dashboard Development
A powerful admin panel for your Laravel app — built with FilamentPHP so you can manage everything without touching the database.