Laravel Events and Listeners

Lesson 39 of 50

78%
1. What Are Events and Listeners?

Laravel Events and Listeners help you organize actions that should happen when something occurs in your application.

  • Event: Represents something that has happened.
  • Listener: Handles an event and performs an action.

Example: Student Registration

When a student registers:

  1. Laravel saves the student's information.
  2. A StudentRegistered event is dispatched.
  3. A listener receives the event.
  4. The listener sends a welcome email.

This separates registration logic from email logic, making the application easier to maintain.

2. Create an Event Class

Use Artisan to create an event:

php artisan make:event StudentRegistered

Laravel creates the event in:

app/Events/StudentRegistered.php

Example event class:

<?php

namespace App\Events;

use App\Models\Student;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

class StudentRegistered
{
    use Dispatchable, SerializesModels;

    public function __construct(
        public Student $student
    ) {}
}

The event carries the student model so that listeners can access the newly registered student's information.

This example assumes your project has an App\Models\Student model.

3. Create a Listener Class

Create a listener using Artisan:

php artisan make:listener SendStudentWelcomeEmail --event=StudentRegistered

Laravel creates:

app/Listeners/SendStudentWelcomeEmail.php

Example listener:

<?php

namespace App\Listeners;

use App\Events\StudentRegistered;
use App\Mail\WelcomeMail;
use Illuminate\Support\Facades\Mail;

class SendStudentWelcomeEmail
{
    public function handle(StudentRegistered $event): void
    {
        $student = $event->student;

        Mail::to($student->email)->send(
            new WelcomeMail($student->name)
        );
    }
}

The handle() method runs when the listener receives the event.

This example assumes the Student model has name and email fields and that the WelcomeMail Mailable exists.

4. Register the Event and Listener

In modern Laravel applications, event discovery can automatically detect listeners in the standard app/Listeners directory when they follow the supported conventions.

If you need to register the mapping manually, open app/Providers/AppServiceProvider.php and use an event listener registration method.

For example, in the boot() method:

use App\Events\StudentRegistered;
use App\Listeners\SendStudentWelcomeEmail;
use Illuminate\Support\Facades\Event;

public function boot(): void
{
    Event::listen(
        StudentRegistered::class,
        SendStudentWelcomeEmail::class
    );
}

Keep the existing imports and methods in your AppServiceProvider. Add the imports at the top of the file and place this code inside its class.

If your project already discovers this listener automatically, you do not need to register it a second time.

Check registered event mappings where supported:

php artisan event:list
5. Dispatch an Event

Dispatch the event after successfully saving the student record.

Example controller method:

<?php

namespace App\Http\Controllers;

use App\Events\StudentRegistered;
use App\Models\Student;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;

class StudentController extends Controller
{
    public function store(Request $request)
    {
        $validated = $request->validate([
            'name' => ['required', 'string', 'max:255'],
            'email' => ['required', 'email', 'max:255', 'unique:students,email'],
            'password' => ['required', 'string', 'min:8'],
        ]);

        $student = Student::create([
            'name' => $validated['name'],
            'email' => $validated['email'],
            'password' => Hash::make($validated['password']),
        ]);

        StudentRegistered::dispatch($student);

        return response()->json([
            'message' => 'Student registered successfully.',
            'student' => [
                'id' => $student->id,
                'name' => $student->name,
                'email' => $student->email,
            ],
        ], 201);
    }
}

This example assumes the Student model allows these fields to be mass-assigned and the database has the corresponding columns.

Never return the student's password in the response. Store passwords using secure hashing.

6. Create Multiple Listeners for One Event

One event can trigger multiple listeners. For example, student registration can send an email and create an administrative notification.

Create another listener:

php artisan make:listener NotifyAdminOfRegistration --event=StudentRegistered

Example listener:

<?php

namespace App\Listeners;

use App\Events\StudentRegistered;
use Illuminate\Support\Facades\Log;

class NotifyAdminOfRegistration
{
    public function handle(StudentRegistered $event): void
    {
        Log::info('A student registered.', [
            'student_id' => $event->student->id,
            'student_name' => $event->student->name,
        ]);
    }
}

Register or discover this listener in the same way as the welcome-email listener.

When StudentRegistered is dispatched, both registered listeners can handle the event.

7. Queue a Listener

Some listener actions, such as sending emails or calling external services, may take time. Laravel allows listeners to be queued.

Add the ShouldQueue interface to the listener class:

use Illuminate\Contracts\Queue\ShouldQueue;

class SendStudentWelcomeEmail implements ShouldQueue
{
    // Keep the existing handle() method here.
}

Keep the listener's constructor and handle() method from the earlier example.

Configure the queue connection in .env:

QUEUE_CONNECTION=database

Create the required queue table if it does not already exist, then run the migrations and start a worker:

php artisan make:queue-table
php artisan migrate
php artisan queue:work

The migration command depends on your Laravel version and existing project setup. Do not create a duplicate jobs table.

With a queued listener, dispatching the event can return before the email is actually sent. A working queue worker is needed to process it.

8. Event and Listener Best Practices
  • Use clear names such as StudentRegistered.
  • Keep event data focused on what listeners need.
  • Keep unrelated business logic out of controllers.
  • Use multiple listeners to separate responsibilities.
  • Queue slow operations when appropriate.
  • Log and monitor listener failures.
  • Be careful with events dispatched inside database transactions.
  • Make queued operations safe to retry.

Important:

If a listener must run only after a database transaction commits, configure it to handle events after commit using Laravel's supported event or queue configuration for your version. This helps prevent listeners from acting on records that were later rolled back.

9. Practice Assignment

Create a student registration event system.

  1. Create a StudentRegistered event.
  2. Create a SendStudentWelcomeEmail listener.
  3. Create a Mailable for the welcome email.
  4. Dispatch the event after saving a student.
  5. Register or verify automatic discovery of the listener.
  6. Create a second listener to log the registration.
  7. Queue the email listener and run a queue worker.
  8. Test the complete registration workflow.

Bonus Task:

Create a FeePaymentCompleted event with listeners for sending a receipt email and recording an administrative log entry.

Quick Quiz

1. What does a Laravel event represent?




2. Which method commonly handles an event in a listener?




3. Which interface allows a listener to be queued?