Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

События

После регистрации нужно отправить письмо, начислить бонус, записать статистику. Если писать всё это в контроллере, он разрастётся. Событие сообщает «пользователь зарегистрировался», а слушатели сами решают, что с этим делать. Основной код о них ничего не знает.

Событие

Событие — простой класс с данными:

php artisan make:event OrderPlaced
namespace App\Events;
 
use App\Models\Order;
use Illuminate\Foundation\Events\Dispatchable;
 
class OrderPlaced
{
    use Dispatchable;
 
    public function __construct(public Order $order) {}
}

Слушатель

Слушатель выполняет одно действие в ответ на событие:

php artisan make:listener SendOrderConfirmation --event=OrderPlaced
namespace App\Listeners;
 
use App\Events\OrderPlaced;
use App\Mail\OrderConfirmation;
use Illuminate\Support\Facades\Mail;
 
class SendOrderConfirmation
{
    public function handle(OrderPlaced $event): void
    {
        Mail::to($event->order->user)->queue(new OrderConfirmation($event->order));
    }
}

Laravel сам находит слушателей в папке app/Listeners и связывает их с событием по типу параметра метода handle().

Вызов события

use App\Events\OrderPlaced;
 
public function store(Request $request)
{
    $order = Order::create([...]);
 
    OrderPlaced::dispatch($order);
 
    return redirect()->route('orders.show', $order);
}

Контроллер только сообщает, что произошло. Чтобы добавить новое действие, пишут ещё один слушатель — контроллер менять не нужно.

Несколько слушателей

На одно событие может откликаться сколько угодно слушателей:

СлушательЧто делает
SendOrderConfirmationОтправляет письмо покупателю
NotifyWarehouseСообщает складу
UpdateSalesStatisticsОбновляет статистику

Слушатель в очереди

Медленного слушателя выполняют в фоне — достаточно добавить интерфейс:

use Illuminate\Contracts\Queue\ShouldQueue;
 
class NotifyWarehouse implements ShouldQueue
{
    public function handle(OrderPlaced $event): void
    {
        // запрос к складской системе
    }
}

Встроенные события

Laravel сам вызывает события в важные моменты: Registered — после регистрации, Login — при входе, PasswordReset — при смене пароля. На них можно подписаться так же, как на свои:

use Illuminate\Auth\Events\Login;
 
class RecordLastLogin
{
    public function handle(Login $event): void
    {
        $event->user->update(['last_login_at' => now()]);
    }
}

Список событий

php artisan event:list

Команда показывает все события и их слушателей.

Частая ошибка

События делают связи в коде неявными: по контроллеру не видно, что после заказа уходит три письма. Используйте их для побочных действий, без которых основная операция всё равно состоялась бы. Если заказ не может существовать без списания товара со склада, это часть основной логики — её место в коде оформления заказа, а не в слушателе.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.