События и слушатели
События в Laravel представлены реализацией паттерна Observer
, что позволяет подписываться и прослушивать события приложения. Как правило, классы событий находятся в директории app/Events
, а классы обработчиков событий — в app/Listeners
.
Класс события
Создаем класс события с помощью artisan-команды:
php artisan make:event CreatePageEvent
Как видите, этот класс события не содержит логики — это просто контейнер для объекта Page
. Трейт SerializesModels
необходим, чтобы корректно сериализовать (представлять в виде строки) Eloquent-модели:
App/Events/CreatePageEvent.php<?php
namespace App\Events;
use App\Models\Page;
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
class CreatePageEvent {
use Dispatchable, InteractsWithSockets, SerializesModels;
public $page;
// Создайте новый экземпляр события @return void
public function __construct(Page $page) {
$this->page = $page;
}
// Определите каналы, по которым должно транслироваться мероприятие @return \Illuminate\Broadcasting\Channel|array
public function broadcastOn() {
return [];
}
}
Обработчик события
Создаем обработчик события с помощью artisan-команды:
php artisan make:listener CreatePageListener --event="CreatePageEvent"
Сразу после добавления новой страницы в базу данных мы добавляем к названию страницы автора и еще раз сохраняем модель:
App/Listeners/CreatePageListener.php<?php
namespace App\Listeners;
use App\Events\CreatePageEvent;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
class CreatePageListener {
// Создайте прослушиватель событий @return void
public function __construct() {
// ...
}
// Обработайте событие @return void @param \App\Events\CreatePageEvent $event
public function handle(CreatePageEvent $event) {
// обрабатываем событие создания новой страницы
$event->page->name .= ' (автор ' . auth()->user()->name . ')';
$event->page->save();
}
}
Чтобы остановить распространение события для других слушателей — нужно вернуть false
из метода handle()
.
Слушатель события
Открываем на редактирование файл класса EventServiceProvider
:
App/Providers/EventServiceProvider.php<?php
namespace App\Providers;
use App\Events\CreatePageEvent;
use App\Listeners\CreatePageListener;
use Illuminate\Auth\Events\Registered;
use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Event;
class EventServiceProvider extends ServiceProvider {
// Сопоставления события с прослушивателем для приложения @var array<class-string, array<int, class-string>>
protected $listen = [
Registered::class => [
SendEmailVerificationNotification::class,
],
// обработчик события создания новой страницы
CreatePageEvent::class => [
CreatePageListener::class,
],
];
// Регистрируйте любые события для вашего приложения @return void
public function boot() {
parent::boot();
}
// Определите, должны ли события и прослушиватели обнаруживаться автоматически @return bool
public function shouldDiscoverEvents()
{
return true;
}
}
Запуск события
Теперь в ресурсном контроллере, который отвечает за создание, редактирование и удаление страниц сайта, возбудим событие:
app/Http/Controllers/PageController.php<?php
namespace App\Http\Controllers\Admin;
use App\Events\CreatePageEvent;
use App\Http\Controllers\Controller;
use App\Models\Page;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
class PageController extends Controller {
// Показывает список всех страниц
public function index() {
$pages = Page::all();
return view('admin.page.index', compact('pages'));
}
// Показывает форму для создания страницы
public function create() {
return view('admin.page.create');
}
// Сохраняет новую страницу в базу данных
public function store(Request $request) {
$page = Page::create($request->all());
// Возбуждаем событие создания страницы
event(new CreatePageEvent($page));
return redirect()->route('admin.page.show', ['page' => $page->id]);
}
// Показывает информацию о странице сайта
public function show(Page $page) {
return view('admin.page.show', compact('page'));
}
// Показывает форму для редактирования страницы
public function edit(Page $page) {
return view('admin.page.edit', compact('page'));
}
// Обновляет страницу (запись в таблице БД)
public function update(Request $request, Page $page) {
$page->update($request->all());
return redirect()->route('admin.page.show', ['page' => $page->id]);
}
// Удаляет страницу (запись в таблице БД)
public function destroy(Page $page) {
$page->delete();
return redirect()->route('admin.page.index');
}
}