Laravel. Наблюдатели за событиями Eloquent
Наблюдатели предоставляют механизм, который позволяет контролировать каждый процесс, происходящий с базой данных. Список событий, которые можно использовать при работе с базой данных, можно посмотреть в трейте HasEvents
. Это retrieved
— при извлечении модели из базы данных, creating
— перед записью новой модели в базу данных, created
— после записи новой модели в базу данных и так далее.
namespace Illuminate\Database\Eloquent\Concerns; use Illuminate\Contracts\Events\Dispatcher; use Illuminate\Events\NullDispatcher; use Illuminate\Support\Arr; use InvalidArgumentException; trait HasEvents { /** * Get the observable event names. * * @return array */ public function getObservableEvents() { return array_merge( [ 'retrieved', 'creating', 'created', 'updating', 'updated', 'saving', 'saved', 'restoring', 'restored', 'replicating', 'deleting', 'deleted', 'forceDeleted', ], $this->observables ); } /* ... */ }
Создадим нового поставщика услуг:
> php artisan make:provider EloquentEventServiceProvider
namespace App\Providers; use App\Models\Page; use Illuminate\Support\ServiceProvider; class EloquentEventServiceProvider extends ServiceProvider { /** * Register services. * * @return void */ public function register() { // ... } /** * Bootstrap services. * * @return void */ public function boot() { Page::creating(function ($page) { $page->name = $page->name . ' (создана ' . auth()->user()->name . ')'; }); } }
Добавим нового поставщика услуг в config/app.php
:
return [ /* ... */ 'providers' => [ /* ... */ App\Providers\EloquentEventServiceProvider::class, ] /* ... */ ]
Теперь перед добавлением новой страницы в базу данных к ее названию добавляется имя автора, который ее создал.
Если нужно наблюдать за множеством событий для разных моделей (Page
, Post
, Category
), то неудобно, что все они будут в методе boot()
сервис-провайдера EloquentEventServiceProvider
. Давайте создадим отдельную директорию app/Observers
и разместим в ней файл класса PageObserver.php
.
<?php namespace App\Observers; use App\Models\Page; class PageObserver { /* * Срабатывает перед записью новой страницы */ public function creating(Page $page) { $page->name = 'Перед созданием, ' . $page->name; } /* * Срабатывает при извлечении из базы данных */ public function retrieved(Page $page) { $page->name = 'При извлечении, ' . $page->name; } /* * Срабатывает перед удалением страницы из БД */ public function deleting(Page $page) { return false; } }
А в сервис-провайдере уже не будем обрабатывать события, а только укажем класс, который будет это делать. Другими словами — зарегистрируем наблюдателя за событиями модели Page
.
namespace App\Providers; use App\Models\Page; use App\Observers\PageObserver; use Illuminate\Support\ServiceProvider; class EloquentEventServiceProvider extends ServiceProvider { /** * Register services. * * @return void */ public function register() { // ... } /** * Bootstrap services. * * @return void */ public function boot() { Page::observe(PageObserver::class); } }
Поскольку метод deleting()
возвращает false
— страницу теперь вообще нельзя удалить.
PageObserver
в отдельной директории app/Observers
, а не в директории app/Listeners
.
Поиск: Laravel • PHP • Web-разработка • Класс • Событие • Теория • Фреймворк