Laravel Events та Listeners у 2026: Подієва Архітектура та Питання на Співбесідах
Повний посібник з системи подій та слухачів у Laravel 12. Реалізація патерну спостерігача, черги для listeners, транзакції бази даних та питання на технічних співбесідах.

Система подій та слухачів у Laravel реалізує патерн спостерігача, розділяючи компоненти додатку шляхом надання різним частинам системи можливості реагувати на дії без прямих залежностей. Коли користувач оформлює замовлення, подія OrderShipped викликається, а окремі слухачі обробляють сповіщення, аналітику та оновлення складу незалежно один від одного.
Laravel 12 автоматично виявляє слухачів у директорії app/Listeners. Будь-який клас із методом handle або __invoke, що має type hint на клас події, автоматично реєструється без конфігураційного файлу.
Як Працює Автоматичне Виявлення Подій у Laravel 12
Починаючи з Laravel 11, EventServiceProvider більше не існує. Фреймворк сканує директорію Listeners та використовує рефлексію для визначення, на які події реагує кожен слухач, базуючись на type hint у сигнатурі методу handle.
<?php
namespace App\Listeners;
use App\Events\OrderShipped;
class SendOrderConfirmation
{
public function handle(OrderShipped $event): void
{
// Надіслати підтверджуючий email на $event->order->user
}
}Наведений вище слухач автоматично реєструється для подій OrderShipped. Це не потребує ручного зв'язування в service provider. Такий підхід зменшує шаблонний код та зберігає зв'язки подія-слухач близько до коду, що їх реалізує.
Для перевірки зареєстрованих слухачів виконайте php artisan event:list. У продакшн середовищі закешуйте маніфест подій командою php artisan event:cache, щоб уникнути сканування директорії при кожному запиті.
Створення Подій та Слухачів за Допомогою Artisan
Laravel надає команди Artisan для генерації каркасу подій та слухачів:
# Згенерувати клас події
php artisan make:event OrderShipped
# Згенерувати слухача, прив'язаного до події
php artisan make:listener SendShipmentNotification --event=OrderShippedЗгенерований клас події використовує три трейти: Dispatchable для статичного методу dispatch(), InteractsWithSockets для broadcasting та SerializesModels для серіалізації моделей Eloquent, коли слухачі додаються до черги.
<?php
namespace App\Events;
use App\Models\Order;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Queue\SerializesModels;
class OrderShipped
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public function __construct(
public Order $order,
) {}
}Клас події — це контейнер для даних. Він зберігає модель Order і нічого більше. Бізнес-логіка належить слухачам, а не подіям.
Відправлення Подій з Контролерів та Сервісів
Події відправляються за допомогою статичного методу dispatch() на класі події:
<?php
namespace App\Http\Controllers;
use App\Events\OrderShipped;
use App\Models\Order;
use Illuminate\Http\Request;
class OrderController extends Controller
{
public function ship(Request $request, Order $order)
{
// Логіка відправки...
OrderShipped::dispatch($order);
return redirect()->route('orders.index');
}
}Для умовної відправки використовуються методи dispatchIf() або dispatchUnless():
// Відправляти тільки якщо замовлення має номер відстеження
OrderShipped::dispatchIf($order->tracking_number !== null, $order);Готовий до співбесід з Laravel?
Практикуйся з нашими інтерактивними симуляторами, flashcards та технічними тестами.
Черги для Слухачів Повільних Операцій
Слухачі, що відправляють електронну пошту, викликають зовнішні API або виконують важкі обчислення, повинні працювати асинхронно. Імплементація ShouldQueue додає слухача до черги:
<?php
namespace App\Listeners;
use App\Events\OrderShipped;
use Illuminate\Contracts\Queue\ShouldQueue;
class SendShipmentNotification implements ShouldQueue
{
public $queue = 'notifications';
public $delay = 60; // Зачекати 60 секунд перед обробкою
public function handle(OrderShipped $event): void
{
// Надіслати сповіщення $event->order->user
}
}Налаштування з'єднання та назви черги виконується через властивості $connection і $queue, або через методи runtime:
public function viaConnection(): string
{
return 'redis';
}
public function viaQueue(): string
{
return $this->event->order->priority === 'high'
? 'high-priority'
: 'default';
}Умовне Додавання до Черги з shouldQueue
Іноді слухач повинен додаватися до черги лише на основі даних події:
public function shouldQueue(OrderShipped $event): bool
{
// Додавати до черги тільки для замовлень понад 100$
return $event->order->total >= 10000;
}Транзакції Бази Даних та Час Подій
Слухачі з черги, відправлені всередині транзакції, можуть бути оброблені до того, як транзакція буде закомічена, що спричиняє помилки відсутніх даних. Існують два рішення:
1. Глобальне налаштування в config/queue.php:
'connections' => [
'redis' => [
'after_commit' => true,
],
],2. Для окремого слухача з ShouldQueueAfterCommit:
use Illuminate\Contracts\Queue\ShouldQueueAfterCommit;
class UpdateInventory implements ShouldQueueAfterCommit
{
public function handle(OrderShipped $event): void
{
// Безпечно запитувати замовлення, транзакція закомічена
}
}Для самих подій імплементуйте ShouldDispatchAfterCommit на класі події:
use Illuminate\Contracts\Events\ShouldDispatchAfterCommit;
class OrderShipped implements ShouldDispatchAfterCommit
{
// Подія відправляється тільки після коміту транзакції
}Унікальні Слухачі для Запобігання Дублікатам
Інтерфейс ShouldBeUnique запобігає додаванню дублікатів слухачів до черги, поки один вже обробляється:
use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Contracts\Queue\ShouldQueue;
class ProcessLicenseKey implements ShouldQueue, ShouldBeUnique
{
public $uniqueFor = 3600; // Блокування закінчується через 1 годину
public function uniqueId(LicensePurchased $event): string
{
return 'license:' . $event->license->id;
}
public function handle(LicensePurchased $event): void
{
// Згенерувати та призначити ключ ліцензії
}
}Якщо той самий ID ліцензії швидко викликає кілька подій, обробляється лише перший слухач. Наступні спроби виявляють, що блокування утримується, і пропускають додавання до черги.
Підписники Подій для Пов'язаних Подій
Коли кілька пов'язаних подій мають спільну логіку обробки, підписники подій групують обробники в одному класі:
<?php
namespace App\Listeners;
use Illuminate\Auth\Events\Login;
use Illuminate\Auth\Events\Logout;
use Illuminate\Events\Dispatcher;
class UserActivitySubscriber
{
public function handleLogin(Login $event): void
{
// Залогувати успішний вхід, оновити last_login
}
public function handleLogout(Logout $event): void
{
// Залогувати вихід, очистити дані сесії
}
public function subscribe(Dispatcher $events): array
{
return [
Login::class => 'handleLogin',
Logout::class => 'handleLogout',
];
}
}Підписники підпорядковуються правилам автоматичного виявлення. Якщо методи-обробники в класі підписника мають правильно типізовані параметри, Laravel реєструє їх автоматично.
Прослуховування Кількох Подій з Union Types
Один слухач може реагувати на кілька типів подій, використовуючи union types з PHP 8:
public function handle(OrderShipped|OrderCancelled $event): void
{
match (true) {
$event instanceof OrderShipped => $this->notifyShipped($event),
$event instanceof OrderCancelled => $this->notifyCancelled($event),
};
}Цей патерн добре працює для сповіщень, які слідують подібній логіці для різних типів подій.
Відкладення Подій з Event::defer
Laravel 12 представив Event::defer() для відкладення відправки подій до завершення блоку коду. Це гарантує слухачам доступ до всіх пов'язаних записів:
use Illuminate\Support\Facades\Event;
Event::defer(function () {
$user = User::create(['name' => 'John']);
$user->posts()->create(['title' => 'Welcome']);
});
// Події для створення User і Post відправляються тутЯкщо всередині closure виникає виключення, відкладені події ніколи не відправляються.
Починай практикувати!
Перевір свої знання з нашими симуляторами співбесід та технічними тестами.
Питання на Співбесідах про Laravel Events та Listeners
Технічні співбесіди часто перевіряють розуміння подієвої архітектури. Ось питання, які відрізняють досвідчених Laravel розробників:
П: Як Laravel 12 реєструє слухачів без EventServiceProvider?
Laravel сканує app/Listeners за допомогою рефлексії. Він читає type hint на методах handle() або __invoke(), щоб визначити, на яку подію реагує кожен слухач. У продакшні закешуйте маніфест командою php artisan event:cache.
П: Коли слухач повинен імплементувати ShouldQueue?
Завжди, коли операція займає більше кількох мілісекунд: відправка email, виклик зовнішніх API, генерація звітів або обробка файлів. Синхронні слухачі блокують HTTP відповідь.
П: Яку проблему вирішує ShouldQueueAfterCommit?
Слухачі з черги можуть бути оброблені до того, як транзакція бази даних буде закомічена. Якщо слухач запитує щойно створений запис, це завершиться невдачею, оскільки дані ще не закомічені. ShouldQueueAfterCommit відкладає відправку до черги до завершення транзакції.
П: Як запобігти дублюванню обробки тієї ж події?
Імплементуйте ShouldBeUnique. Визначте uniqueId() для повернення ключа кешу на основі даних події. Слухач отримує атомарне блокування, і дублікати відправок пропускаються, якщо блокування утримується.
П: Яка різниця між слухачем подій та підписником подій?
Слухач обробляє один тип події. Підписник — це клас, який реєструє обробники для кількох пов'язаних подій в одному місці, корисний для групування подій автентифікації або аудит-логування.
Значення Laravel Events для Масштабованих Додатків
- Події розділяють компоненти, дозволяючи функціям на кшталт сповіщень та аналітики розвиватися незалежно
- Слухачі з черги переносять повільні операції, зберігаючи швидкі HTTP відповіді
ShouldQueueAfterCommitзапобігає race conditions між воркерами черги та транзакціями бази даних- Автоматичне виявлення в Laravel 12 усуває конфігураційні накладні витрати, зберігаючи логіку слухачів близько до реалізації
- Підписники подій консолідують обробку пов'язаних подій, зменшуючи розкидання файлів для поширених патернів, таких як відстеження активності користувача
- Модуль
/technologies/laravel/interview-questions/events-listenersна SharpSkill охоплює ці патерни з інтерактивними питаннями
Чи знайдеш ти помилку в Laravel?
Справжній фрагмент коду, прихована помилка, одна спроба на день. Щоб спробувати, акаунт не потрібен.

Автор:
Anthony Fillion-MailletЗасновник SharpSkill
Fullstack-розробник понад 10 років. Керує SharpSkill і відповідає за все, що тут публікується.
Оновлено 20 серпня 2026 р.
Теги
Поділитися
Пов'язані статті

Питання на співбесіду PHP Laravel Developer 2026: Повний посібник з підготовки
Комплексний посібник з технічних питань на співбесіду для PHP Laravel розробників у 2026 році. Охоплює Eloquent ORM, Service Container, авторизацію, черги та тестування.

Laravel 12 у 2026 році: нові можливості, Starter Kits та питання для співбесіди
Повний огляд Laravel 12: перероблені Starter Kits на основі React 19, Vue 3, Svelte 5 та Livewire 4, інтеграція WorkOS AuthKit, оновлення залежностей до Carbon 3 та PHP 8.2+, покроковий посібник з оновлення з Laravel 11 та актуальні питання для технічних співбесід у 2026 році.

Рішення Laravel: Розширені Патерни, Налагодження та Питання на Співбесіді 2026
Комплексний посібник з розширених архітектурних патернів Laravel, технік налагодження з Telescope та найпоширеніших питань на співбесідах для розробників Laravel.