One of the most widely used design patterns in Laravel is Observer.
Actually, there are two Laravel features for this pattern:
The general idea is this:
Look at a typical Event/Listener example from Laravel Breeze:
app/Http/Controllers/Auth/RegisteredUserController.php:
use Illuminate\Auth\Events\Registered; // ... class RegisteredUserController extends Controller{ public function store(Request $request): RedirectResponse { // ... validation $user = User::create([ 'name' => $request->name, 'email' => $request->email, 'password' => Hash::make($request->password), ]); event(new Registered($user));
The registration Controller fires the event Registered
that can be listened to by others.
Inside that Registered
Event class, which comes from Laravel core, we have $user
as a property.
Illuminate/Auth/Events/Registered.php:
use Illuminate\Queue\SerializesModels; class Registered{ use SerializesModels; public $user; public function __construct($user) { $this->user = $user; }}
And then, for example, we want to create a listener to auto-create a Team for that new user.
Then, all we need to do:
php artisan make:listener CreateTeamListener
Registered
Event as a parameter, and the Listener will auto-listen for that Eventapp/Listeners/CreateTeamListener.php:
use App\Models\Team;use Illuminate\Auth\Events\Registered; // ... class CreateTeamListener{ public function handle(Registered $event): void { // Access the user using $event->user... Team::create([ 'name' => $event->user->name . "'s Team", 'user_id' => $event->user->id, ]); }}
With recent Laravel changes, we don't even need to register that Listener anywhere. The event discovery will take care of it.
Eloquent Observers just happens to be a more convenient "wrapper" implementation of events/listeners.
For example...