# Laravel Events та Listeners у 2026: Подієва Архітектура та Питання на Співбесідах > Повний посібник з системи подій та слухачів у Laravel 12. Реалізація патерну спостерігача, черги для listeners, транзакції бази даних та питання на технічних співбесідах. - Published: 2026-08-20 - Updated: 2026-08-20 - Author: Anthony Fillion-Maillet - Tags: laravel, events, listeners, php, подієва архітектура - Reading time: 12 min --- Система подій та слухачів у Laravel реалізує [патерн спостерігача](https://refactoring.guru/design-patterns/observer), розділяючи компоненти додатку шляхом надання різним частинам системи можливості реагувати на дії без прямих залежностей. Коли користувач оформлює замовлення, подія `OrderShipped` викликається, а окремі слухачі обробляють сповіщення, аналітику та оновлення складу незалежно один від одного. > **Автоматичне Виявлення Подій у Laravel 12** > > Laravel 12 автоматично виявляє слухачів у директорії `app/Listeners`. Будь-який клас із методом `handle` або `__invoke`, що має type hint на клас події, автоматично реєструється без конфігураційного файлу. ## Як Працює Автоматичне Виявлення Подій у Laravel 12 Починаючи з Laravel 11, `EventServiceProvider` більше не існує. Фреймворк сканує директорію `Listeners` та використовує рефлексію для визначення, на які події реагує кожен слухач, базуючись на type hint у сигнатурі методу `handle`. ```php // app/Listeners/SendOrderConfirmation.php order->user } } ``` Наведений вище слухач автоматично реєструється для подій `OrderShipped`. Це не потребує ручного зв'язування в service provider. Такий підхід зменшує шаблонний код та зберігає зв'язки подія-слухач близько до коду, що їх реалізує. Для перевірки зареєстрованих слухачів виконайте `php artisan event:list`. У продакшн середовищі закешуйте маніфест подій командою `php artisan event:cache`, щоб уникнути сканування директорії при кожному запиті. ## Створення Подій та Слухачів за Допомогою Artisan Laravel надає команди Artisan для генерації каркасу подій та слухачів: ```bash # Згенерувати клас події php artisan make:event OrderShipped # Згенерувати слухача, прив'язаного до події php artisan make:listener SendShipmentNotification --event=OrderShipped ``` Згенерований клас події використовує три трейти: `Dispatchable` для статичного методу `dispatch()`, `InteractsWithSockets` для broadcasting та `SerializesModels` для серіалізації моделей Eloquent, коли слухачі додаються до черги. ```php // app/Events/OrderShipped.php route('orders.index'); } } ``` Для умовної відправки використовуються методи `dispatchIf()` або `dispatchUnless()`: ```php // Відправляти тільки якщо замовлення має номер відстеження OrderShipped::dispatchIf($order->tracking_number !== null, $order); ``` ## Черги для Слухачів Повільних Операцій Слухачі, що відправляють електронну пошту, викликають зовнішні API або виконують важкі обчислення, повинні працювати асинхронно. Імплементація `ShouldQueue` додає слухача до черги: ```php // app/Listeners/SendShipmentNotification.php order->user } } ``` Налаштування з'єднання та назви черги виконується через властивості `$connection` і `$queue`, або через методи runtime: ```php public function viaConnection(): string { return 'redis'; } public function viaQueue(): string { return $this->event->order->priority === 'high' ? 'high-priority' : 'default'; } ``` ### Умовне Додавання до Черги з shouldQueue Іноді слухач повинен додаватися до черги лише на основі даних події: ```php public function shouldQueue(OrderShipped $event): bool { // Додавати до черги тільки для замовлень понад 100$ return $event->order->total >= 10000; } ``` ## Транзакції Бази Даних та Час Подій Слухачі з черги, відправлені всередині транзакції, можуть бути оброблені до того, як транзакція буде закомічена, що спричиняє помилки відсутніх даних. Існують два рішення: **1. Глобальне налаштування** в `config/queue.php`: ```php 'connections' => [ 'redis' => [ 'after_commit' => true, ], ], ``` **2. Для окремого слухача** з `ShouldQueueAfterCommit`: ```php use Illuminate\Contracts\Queue\ShouldQueueAfterCommit; class UpdateInventory implements ShouldQueueAfterCommit { public function handle(OrderShipped $event): void { // Безпечно запитувати замовлення, транзакція закомічена } } ``` Для самих подій імплементуйте `ShouldDispatchAfterCommit` на класі події: ```php use Illuminate\Contracts\Events\ShouldDispatchAfterCommit; class OrderShipped implements ShouldDispatchAfterCommit { // Подія відправляється тільки після коміту транзакції } ``` ## Унікальні Слухачі для Запобігання Дублікатам Інтерфейс `ShouldBeUnique` запобігає додаванню дублікатів слухачів до черги, поки один вже обробляється: ```php 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 // app/Listeners/UserActivitySubscriber.php 'handleLogin', Logout::class => 'handleLogout', ]; } } ``` Підписники підпорядковуються правилам автоматичного виявлення. Якщо методи-обробники в класі підписника мають правильно типізовані параметри, Laravel реєструє їх автоматично. ## Прослуховування Кількох Подій з Union Types Один слухач може реагувати на кілька типів подій, використовуючи union types з PHP 8: ```php 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()` для відкладення відправки подій до завершення блоку коду. Це гарантує слухачам доступ до всіх пов'язаних записів: ```php 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](/technologies/laravel/interview-questions/events-listeners) охоплює ці патерни з інтерактивними питаннями --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/uk/blog/laravel/laravel-events-listeners-event-driven-architecture