Система событий Laravel феноменальна, когда дело доходит до работы со сложными данными в наших веб-приложениях, поскольку она является краеугольным камнем для создания несвязанных и абсолютно сложных приложений. В этом руководстве очень подробно рассказывается о реализации и использовании прослушивания событий, особенно в 2024 году, предлагая свежий взгляд на самый обширный контент и подробные примеры кода прослушивателей событий в Laravel 11.
*(A) Понимание сути событий и слушателей
*
Итак, давайте разберем их: события в Laravel представляют определенные события внутри приложения. Слушатели — это классы, которые будут реагировать на все такие события приложения. Этот шаблон продолжает способствовать разделению задач и позволяет создавать более модульный и тестируемый код.
*(B) Создание события
*
Давайте начнем с создания даже сложного события, для которого мы будем использовать команду Artisan, чтобы лучше объяснить, мы настоятельно рекомендуем вам тоже это сделать
php artisan make:event OrderPlaced
Эта команда создаст новый класс событий в каталоге app/Events. Давайте рассмотрим более подробный класс событий
`пространство имен App\Events;
использовать приложение\модели\заказ;
используйте приложение\модели\пользователь;
используйте Illuminate\Foundation\Events\Dispatchable;
используйте Illuminate\Queue\SerializesModels;
используйте Illuminate\Broadcasting\InteractsWithSockets;
используйте Illuminate\Broadcasting\PrivateChannel;
используйте Illuminate\Contracts\Broadcasting\ShouldBroadcast;
класс OrderPlaced реализует СледуетBroadcast
{
используйте Dispatchable, InteractsWithSockets, SerializesModels;
public $order; public $user; /** * Create a new event instance. * * @param \App\Models\Order $order * @param \App\Models\User $user * @return void */ public function __construct(Order $order, User $user) { $this->order = $order; $this->user = $user; } /** * Get the channels the event should broadcast on. * * @return \Illuminate\Broadcasting\Channel|array */ public function broadcastOn() { return new PrivateChannel('orders.'.$this->user->id); } /** * The event's broadcast name. * * @return string */ public function broadcastAs() { return 'order.placed'; }
}`
В этом расширенном примере мы включили модели заказа и пользователя. Черта SerializesModels гарантирует правильную сериализацию и десериализацию наших моделей Eloquent, когда событие передается прослушивателям в очереди. Мы также реализовали интерфейс ShouldBroadcast и определили методы broadcastOn и broadcastAs, позволяющие транслировать это событие на веб-сокеты для обновлений в режиме реального времени.
*Создание нескольких прослушивателей
*
Для одного события нам может потребоваться несколько слушателей. Давайте создадим два прослушивателя для нашего события OrderPlaced, чтобы еще больше расширить пример. Я просто хочу, чтобы вы, ребята, поняли суть всего. Для этого см. пример кода ниже
php artisan make:listener SendOrderConfirmation --event=OrderPlaced
php artisan make:listener UpdateInventory --event=OrderPlaced
Итак, теперь вы понимаете, что эта командная строка предоставит нам пару новых классов прослушивателей в нашем каталоге app/Listeners. Теперь дело в том, что здесь ниже мы рассмотрим прослушиватель SendOrderConfirmation и посмотрим, как с ним работать и как он продвигается дальше
`пространство имен App\Listeners;
используйте App\Events\OrderPlaced;
используйте App\Mail\OrderConfirmation;
используйте Illuminate\Contracts\Queue\ShouldQueue;
используйте Illuminate\Queue\InteractsWithQueue;
используйте Illuminate\Support\Facades\Mail;
используйте Illuminate\Support\Facades\Log;
класс SendOrderConfirmation реализует MustQueue
{
используйте InteractsWithQueue;
/** * The number of times the job may be attempted. * * @var int */ public $tries = 3; /** * Handle the event. * * @param \App\Events\OrderPlaced $event * @return void */ public function handle(OrderPlaced $event) { $order = $event->order; $user = $event->user; try { Mail::to($user->email)->send(new OrderConfirmation($order)); Log::info('Order confirmation email sent', ['order_id' => $order->id, 'user_id' => $user->id]); } catch (\Exception $e) { Log::error('Failed to send order confirmation email', ['order_id' => $order->id, 'user_id' => $user->id, 'error' => $e->getMessage()]); $this->fail($e); } } /** * Handle a job failure. * * @param \App\Events\OrderPlaced $event * @param \Throwable $exception * @return void */ public function failed(OrderPlaced $event, $exception) { Log::error('Order confirmation listener failed', ['order_id' => $event->order->id, 'user_id' => $event->user->id, 'error' => $exception->getMessage()]); }
}`
Этот прослушиватель реализовал интерфейс ShouldQueue, указывающий, что его следует поставить в очередь. Мы добавили обработку ошибок, ведение журнала и определили метод обработки сбоев. Свойство $tries будет настроено таким образом, чтобы в случае неудачи было разрешено несколько попыток.
Теперь давайте посмотрим на прослушиватель UpdateInventory
`пространство имен App\Listeners;
используйте App\Events\OrderPlaced;
используйте Illuminate\Contracts\Queue\ShouldQueue;
используйте Illuminate\Queue\InteractsWithQueue;
используйте Illuminate\Support\Facades\DB;
используйте Illuminate\Support\Facades\Log;
класс UpdateInventory реализует MustQueue
{
используйте InteractsWithQueue;
/** * Handle the event. * * @param \App\Events\OrderPlaced $event * @return void */ public function handle(OrderPlaced $event) { $order = $event->order; DB::transaction(function () use ($order) { foreach ($order->items as $item) { $product = $item->product; if ($product->stock quantity) { throw new \Exception("Insufficient stock for product: {$product->id}"); } $product->decrement('stock', $item->quantity); Log::info("Inventory updated", ['product_id' => $product->id, 'quantity' => $item->quantity]); } }); } /** * Handle a job failure. * * @param \App\Events\OrderPlaced $event * @param \Throwable $exception * @return void */ public function failed(OrderPlaced $event, $exception) { Log::error('Failed to update inventory', ['order_id' => $event->order->id, 'error' => $exception->getMessage()]); }
}`
Теперь вы понимаете, что этот прослушиватель существует по таким причинам, как обновление инвентаря на основе позиций заказа и т. д. Мы включили обновление инвентаря в транзакцию базы данных, чтобы обеспечить согласованность данных. Мы также добавили проверку ошибок, чтобы предотвратить отрицательные запасы, и включили журналирование успешных обновлений и сбоев.
*Регистрация событий и слушателей
*
Мы будем регистрировать эти события и прослушиватели в EventServiceProvider
`используйте App\Events\OrderPlaced;
используйте App\Listeners\SendOrderConfirmation;
используйте App\Listeners\UpdateInventory;
класс EventServiceProvider расширяет ServiceProvider
{
/**
* Сопоставления прослушивателей событий для приложения.
*
* @var массив
*/
защищенный $listen = [
OrderPlaced::class => [
SendOrderConfirmation::class,
UpdateInventory::class,
],
];
/** * Register any events for your application. * * @return void */ public function boot() { parent::boot(); // }
}`
Отправка событий:
Мы можем отправить событие из контроллера или класса обслуживания
`используйте App\Events\OrderPlaced;
используйте App\Models\Order;
используйте Illuminate\Http\Request;
используйте Illuminate\Support\Facades\DB;
класс OrderController расширяет контроллер
{
/**
* Разместите новый заказ.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\JsonResponse
*/
публичная функция PlaceOrder(Request $request)
{
$user = auth()->user();
DB::transaction(function () use ($request, $user) { $order = Order::create($request->all()); $order->user()->associate($user); $order->save(); event(new OrderPlaced($order, $user)); }); return response()->json(['message' => 'Order placed successfully', 'order_id' => $order->id]); }
}`
В этом примере мы включили создание заказа и отправку событий в транзакцию базы данных, чтобы гарантировать, что оба события выполняются успешно или не выполняются вообще.
Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.
Copyright© 2022 湘ICP备2022001581号-3