Das Ereignissystem von Laravel ist phänomenal, wenn es um den Umgang mit den komplexen Daten in unseren Web-Apps geht, da es einen Eckpfeiler für die Erstellung entkoppelter und absolut komplexer Apps darstellt. Dieser Leitfaden erläutert äußerst detaillierte Punkte zur Implementierung und Nutzung von Event-Listener, insbesondere im Jahr 2024, und bietet eine neue Perspektive mit den umfangreichsten Inhalten und detaillierten Codebeispielen für Event-Listener in Laravel 11.
*(A) Den Kern hinter Ereignissen und Zuhörern verstehen
*
Also, lasst uns sie aufschlüsseln: Die Ereignisse in Laravel repräsentieren bestimmte Vorkommnisse innerhalb einer App. Listener sind die Klassen, die auf alle derartigen App-Ereignisse reagieren würden. Dieses Muster fördert weiterhin eine Trennung der Belange und ermöglicht einen modulareren und testbareren Code.
*(B) Erstellen eines Ereignisses
*
Beginnen wir damit, ein sogar komplexes Ereignis zu erstellen. Zur besseren Erklärung verwenden wir den Artisan-Befehl. Wir empfehlen Ihnen dringend, dies auch zu tun
php artisan make:event OrderPlaced
Dieser Befehl generiert eine neue Ereignisklasse im Verzeichnis app/Events. Lassen Sie uns eine detailliertere Ereignisklasse untersuchen
`namespace App\Events;
use App\Models\Order;
verwenden Sie App\Models\User;
verwenden Sie Illuminate\Foundation\Events\Dispatchable;
verwenden Sie Illuminate\Queue\SerializesModels;
verwenden Sie Illuminate\Broadcasting\InteractsWithSockets;
verwenden Sie Illuminate\Broadcasting\PrivateChannel;
verwenden Sie Illuminate\Contracts\Broadcasting\ShouldBroadcast;
Klasse OrderPlaced implementiert ShouldBroadcast
{
Verwenden Sie 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'; }
}`
In diesem erweiterten Beispiel haben wir sowohl das Bestell- als auch das Benutzermodell einbezogen. Das Merkmal SerializesModels stellt sicher, dass unsere Eloquent-Modelle korrekt serialisiert und deserialisiert werden, wenn das Ereignis an Listener in der Warteschlange übergeben wird. Wir haben außerdem die Schnittstelle ShouldBroadcast implementiert und die Methoden broadcastOn und broadcastAs definiert, sodass dieses Ereignis für Echtzeitaktualisierungen an Websockets gesendet werden kann.
*Mehrere Listener erstellen
*
Für ein einzelnes Ereignis benötigen wir möglicherweise mehrere Zuhörer. Erstellen wir zwei Listener für unser OrderPlaced-Ereignis, um das Beispiel weiter zu erweitern. Ich möchte nur, dass ihr sicherstellt, dass ihr den Kern von allem versteht. Sehen Sie sich hierzu bitte das Codebeispiel unten an
php artisan make:listener SendOrderConfirmation --event=OrderPlaced
php artisan make:listener UpdateInventory --event=OrderPlaced
Jetzt verstehen Sie also, dass diese Befehlszeile uns ein paar neue Listener-Klassen in unserem Verzeichnis app/Listeners bescheren würde. Die Sache ist nun die, hier unten würden wir den SendOrderConfirmation-Listener untersuchen und sehen, wie es weitergeht
`namespace App\Listeners;
use App\Events\OrderPlaced;
verwenden Sie App\Mail\OrderConfirmation;
verwenden Sie Illuminate\Contracts\Queue\ShouldQueue;
verwenden Sie Illuminate\Queue\InteractsWithQueue;
verwenden Sie Illuminate\Support\Facades\Mail;
verwenden Sie Illuminate\Support\Facades\Log;
Klasse SendOrderConfirmation implementiert ShouldQueue
{
verwenden Sie 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()]); }
}`
Dieser Listener hat die Schnittstelle ShouldQueue implementiert und gibt an, dass er in die Warteschlange gestellt werden soll. Wir haben Fehlerbehandlung und Protokollierung hinzugefügt und eine fehlgeschlagene Methode zur Behandlung von Fehlern definiert. Die Eigenschaft „$tries“ wird so eingestellt, dass im Falle eines Fehlers mehrere Versuche möglich sind.
Schauen wir uns nun den UpdateInventory-Listener an
`namespace App\Listeners;
use App\Events\OrderPlaced;
verwenden Sie Illuminate\Contracts\Queue\ShouldQueue;
verwenden Sie Illuminate\Queue\InteractsWithQueue;
verwenden Sie Illuminate\Support\Facades\DB;
verwenden Sie Illuminate\Support\Facades\Log;
Klasse UpdateInventory implementiert ShouldQueue
{
verwenden Sie 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()]); }
}`
Nun verstehen Sie, dass dieser Listener zum Beispiel dazu dient, den Lagerbestand basierend auf den Bestellartikeln usw. zu aktualisieren. Wir haben die Lagerbestandsaktualisierung in eine Datenbanktransaktion eingebunden, um die Datenkonsistenz sicherzustellen. Wir haben außerdem eine Fehlerprüfung hinzugefügt, um negative Bestände zu verhindern, und eine Protokollierung für erfolgreiche Aktualisierungen und Fehler integriert.
*Ereignisse und Zuhörer registrieren
*
Wir werden diese Ereignisse und Listener im EventServiceProvider
`use App\Events\OrderPlaced;
verwenden Sie App\Listeners\SendOrderConfirmation;
verwenden Sie App\Listeners\UpdateInventory;
Klasse EventServiceProvider erweitert ServiceProvider
{
/**
* Die Ereignis-Listener-Zuordnungen für die Anwendung.
*
* @var-Array
*/
protected $listen = [
OrderPlaced::class => [
SendOrderConfirmation::class,
UpdateInventory::class,
],
];
/** * Register any events for your application. * * @return void */ public function boot() { parent::boot(); // }
}`
Versenden von Ereignissen:
Wir können das Ereignis von einem Controller oder einer Serviceklasse aus versenden
`use App\Events\OrderPlaced;
verwenden Sie App\Models\Order;
verwenden Sie Illuminate\Http\Request;
verwenden Sie Illuminate\Support\Facades\DB;
Klasse OrderController erweitert Controller
{
/**
* Geben Sie eine neue Bestellung auf.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\JsonResponse
*/
öffentliche Funktion 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 diesem Beispiel haben wir die Auftragserstellung und den Ereignisversand in eine Datenbanktransaktion eingebunden, um sicherzustellen, dass beides erfolgreich oder gar nicht erfolgt.
Haftungsausschluss: Alle bereitgestellten Ressourcen stammen teilweise aus dem Internet. Wenn eine Verletzung Ihres Urheberrechts oder anderer Rechte und Interessen vorliegt, erläutern Sie bitte die detaillierten Gründe und legen Sie einen Nachweis des Urheberrechts oder Ihrer Rechte und Interessen vor und senden Sie ihn dann an die E-Mail-Adresse: [email protected] Wir werden die Angelegenheit so schnell wie möglich für Sie erledigen.
Copyright© 2022 湘ICP备2022001581号-3