PHP
Handling Model Lifecycle Events with Eloquent Observers
Learn to execute custom logic automatically when Eloquent models are created, updated, deleted, or retrieved using model events and dedicated observers.
<?php
// 1. Create an Observer (e.g., php artisan make:observer UserObserver --model=User)
namespace App\Observers;
use App\Models\User;
class UserObserver
{
public function creating(User $user)
{
// Logic before a user is created
$user->uuid = (string) \Illuminate\Support\Str::uuid();
}
public function created(User $user)
{
// Logic after a user has been created
\Log::info('User ' . $user->id . ' created.');
}
public function deleting(User $user)
{
// Logic before a user is deleted (e.g., delete related files or perform cleanup)
// unlink(storage_path('app/avatars/' . $user->avatar));
}
public function updated(User $user)
{
// Logic after a user has been updated
if ($user->isDirty('email')) {
\Log::info('User ' . $user->id . ' email updated from ' . $user->getOriginal('email') . ' to ' . $user->email);
}
}
}
// 2. Register the Observer (e.g., in App\Providers\AppServiceProvider.php's boot method)
namespace App\Providers;
use App\Models\User;
use App\Observers\UserObserver;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
public function boot()
{
User::observe(UserObserver::class);
}
}
// Usage: These methods will automatically trigger when User model events occur.
// Assuming App\Models\User exists
// $user = User::create(['name' => 'Test', 'email' => '[email protected]', 'password' => 'secret']); // creating & created
// $user->email = '[email protected]';
// $user->save(); // updated
// $user->delete(); // deleting & deleted
How it works: Eloquent observers provide a clean, centralized way to group listeners for model events. Instead of defining event listeners in a service provider or separate files for each event, an observer class can handle multiple events (`creating`, `created`, `updating`, `updated`, `deleting`, `deleted`, `retrieving`, `restoring`, `restored`) for a single model. This allows you to execute custom logic automatically at various points in a model's lifecycle, like generating UUIDs, logging changes, or cleaning up related data.