Le système d'événements de Laravel est phénoménal lorsqu'il s'agit de traiter les données complexes de nos applications Web, car il constitue la pierre angulaire de la création d'applications découplées et absolument complexes. Ce guide explique des points extrêmement détaillés sur la mise en œuvre et l'utilisation de l'écoute d'événements, en particulier en 2024, offrant une nouvelle perspective avec le contenu le plus complet et des exemples de code détaillés pour les auditeurs d'événements dans Laravel 11.
*(A) Comprendre le cœur des événements et des auditeurs
*
Alors, décomposons-les, les événements de Laravel représentent des occurrences spécifiques à l'intérieur d'une application. Les auditeurs sont les classes qui répondraient à tous ces événements d’application. Ce modèle continue de promouvoir une séparation des préoccupations et permet un code plus modulaire et testable.
*(B) Créer un événement
*
Commençons par créer un événement, même complexe, pour lequel nous utiliserons la commande Artisan pour mieux expliquer, nous vous suggérons fortement de le faire aussi
php artisan make:event OrderPlaced
Cette commande générera une nouvelle classe d'événement dans le répertoire app/Events. Examinons une classe d'événements plus détaillée
`espace de noms AppEvents;
utilisez AppModelsOrder ;
utiliser AppModelsUser ;
utilisez IlluminateFoundationEventsDispatchable;
utiliser IlluminateQueueSerializesModels;
utilisez IlluminateBroadcastingInteractsWithSockets ;
utilisez IlluminateBroadcastingPrivateChannel;
utilisez IlluminateContractsBroadcastingShouldBroadcast ;
classe OrderPlaced implémente ShouldBroadcast
{
utilisez 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'; }
}`
Dans cet exemple développé, nous avons inclus à la fois les modèles Commande et Utilisateur. Le trait SerializesModels garantit que nos modèles Eloquent sont correctement sérialisés et désérialisés lorsque l'événement est transmis aux auditeurs en file d'attente. Nous avons également implémenté l'interface ShouldBroadcast et défini les méthodes broadcastOn et broadcastAs, permettant à cet événement d'être diffusé sur des websockets pour des mises à jour en temps réel.
*Création de plusieurs auditeurs
*
Pour un seul événement, nous pourrions vouloir plusieurs auditeurs. Créons deux auditeurs pour notre événement OrderPlaced pour développer davantage l'exemple. Je veux juste que vous vous assuriez de bien comprendre l'essentiel. Donc, pour cela, veuillez consulter l'exemple de code ci-dessous
php artisan make:listener SendOrderConfirmation --event=OrderPlaced
php artisan make:listener UpdateInventory --event=OrderPlaced
Donc, vous comprendrez maintenant que cette ligne de commande nous apporterait quelques nouvelles classes d'écoute dans notre répertoire app/Listeners. Maintenant, le fait est que, ci-dessous, nous examinerions l'écouteur SendOrderConfirmation et verrons comment il progresse davantage
`espace de noms AppListeners;
utilisez AppEventsOrderPlaced ;
utilisez AppMailOrderConfirmation ;
utilisez IlluminateContractsQueueShouldQueue;
utilisez IlluminateQueueInteractsWithQueue;
utilisez IlluminateSupportFacadesMail;
utilisez IlluminateSupportFacadesLog;
la classe SendOrderConfirmation implémente ShouldQueue
{
utiliser 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()]); }
}`
Cet écouteur a implémenté l'interface ShouldQueue, indiquant qu'il doit être mis en file d'attente. Nous avons ajouté la gestion des erreurs, la journalisation et défini une méthode d'échec pour gérer les échecs. La propriété $tries serait définie pour autoriser plusieurs tentatives en cas d'échec.
Maintenant, regardons l'écouteur UpdateInventory
`espace de noms AppListeners;
utilisez AppEventsOrderPlaced ;
utilisez IlluminateContractsQueueShouldQueue;
utilisez IlluminateQueueInteractsWithQueue;
utilisez IlluminateSupportFacadesDB ;
utilisez IlluminateSupportFacadesLog;
la classe UpdateInventory implémente ShouldQueue
{
utiliser 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 < $item->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()]); }
}`
Maintenant, vous comprendrez que cet auditeur est là pour des raisons telles que la mise à niveau de l'inventaire en fonction des articles commandés, etc. Nous avons enveloppé la mise à jour de l'inventaire dans une transaction de base de données pour garantir la cohérence des données. Nous avons également ajouté une vérification des erreurs pour éviter les stocks négatifs et inclus la journalisation des mises à jour réussies et des échecs.
*Enregistrement des événements et des auditeurs
*
Nous enregistrerons ces événements et auditeurs dans EventServiceProvider
`use AppEventsOrderPlaced;
utilisez AppListenersSendOrderConfirmation ;
utilisez AppListenersUpdateInventory ;
class EventServiceProvider extends ServiceProvider
{
/**
* The event listener mappings for the application.
*
* @var array
*/
protected $listen = [
OrderPlaced::class => [
SendOrderConfirmation::class,
UpdateInventory::class,
],
];
/** * Register any events for your application. * * @return void */ public function boot() { parent::boot(); // }
}`
Dispatching Events:
We can dispatch the event from a controller or service class
`use App\Events\OrderPlaced;
use App\Models\Order;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class OrderController extends Controller
{
/**
* Place a new order.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function 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]); }
}`
In this example, we have wrapped the order creation and event dispatching in a database transaction to ensure that both occur successfully or not at all.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!