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.
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.
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">// } }
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}"); } }
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; }
ClearProjectCache, that logs "Clearing project cache" when TaskCreated fires.EventServiceProvider alongside the existing notification listener.storage/logs/laravel.log to confirm both listeners executed.try-catch blocks if they perform risky operations.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.
Master service-oriented task management in Laravel. Learn to encapsulate task creation and user assignment logic within a service layer for cleaner code.
Read moreLearn how to implement a service layer in Laravel to encapsulate business logic, reduce controller bloat, and build a more maintainable, testable application.
Introduction to Laravel Events and Listeners
Job Chaining and Batching
Feature Testing Fundamentals
Mocking Services and Repositories in Tests
Testing Events and Jobs
Database Factories and Seeding
API Versioning Strategies
Advanced Request Filtering and Sorting
Handling File Uploads in REST APIs
Real-time Notifications with Broadcasting
Using Observers for Model Lifecycle Hooks
Implementing Policies for Authorization
Customizing Authentication Guards
Rate Limiting API Endpoints
Eloquent Performance Optimization
Caching Strategies for Performance
Using Traits for Code Reuse
Advanced Dependency Injection with Service Providers
Command Line Tools with Artisan
Scheduled Tasks and Cron Jobs
Integrating Third-Party Services
Handling Webhooks
Logging and Monitoring
Database Migrations Best Practices
Advanced Testing: Integration Tests
Testing API Authentication
Code Quality and Static Analysis
Project Structure for Large Applications
Environment and Configuration Management
Deploying Laravel Applications
Database Indexing Strategies
Using Value Objects
Strategy Pattern for Business Rules
Advanced Queue Monitoring
Building a Search API
Handling Concurrency and Race Conditions
API Documentation with OpenAPI
Testing with Test Doubles
Implementing Multi-Tenancy
Refactoring Legacy Code
Using Middleware for Feature Flags
Building Reusable Packages
Performance Profiling
Secure API Design
Event Sourcing Concepts