Heim  >  Artikel  >  Backend-Entwicklung  >  Wie und wann man Ereignis-Listener in praktischen Codebeispielen von Laravel verwendet

Wie und wann man Ereignis-Listener in praktischen Codebeispielen von Laravel verwendet

王林
王林Original
2024-08-16 07:03:02253Durchsuche

How & When To Use Event Listeners in Laravel  Practical Code Examples

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 mit der Erstellung eines sogar komplexen Ereignisses. 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 AppEvents;

AppModelsOrder verwenden;
verwenden Sie AppModelsUser;
verwenden Sie IlluminateFoundationEventsDispatchable;
verwenden Sie IlluminateQueueSerializesModels;
verwenden Sie IlluminateBroadcastingInteractsWithSockets;
verwenden Sie IlluminateBroadcastingPrivateChannel;
Verwenden Sie IlluminateContractsBroadcastingShouldBroadcast;

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. Die Eigenschaft SerializesModels stellt sicher, dass unsere Eloquent-Modelle korrekt serialisiert und deserialisiert werden, wenn das Ereignis an Listener in der Warteschlange übergeben wird. Wir haben auch die Schnittstelle ShouldBroadcast implementiert und die Methoden broadcastOn und broadcastAs definiert, sodass dieses Ereignis für Echtzeitaktualisierungen an Websockets gesendet werden kann.

*Mehrere Zuhörer 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 dazu 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 AppListeners;

AppEventsOrderPlaced verwenden;
verwenden Sie AppMailOrderConfirmation;
verwenden Sie IlluminateContractsQueueShouldQueue;
verwenden Sie IlluminateQueueInteractsWithQueue;
verwenden Sie IlluminateSupportFacadesMail;
verwenden Sie IlluminateSupportFacadesLog;

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 AppListeners;

AppEventsOrderPlaced verwenden;
verwenden Sie IlluminateContractsQueueShouldQueue;
verwenden Sie IlluminateQueueInteractsWithQueue;
verwenden Sie IlluminateSupportFacadesDB;
verwenden Sie IlluminateSupportFacadesLog;

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 < $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()]);
}

}`

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

registrieren

`verwenden Sie AppEventsOrderPlaced;
verwenden Sie AppListenersSendOrderConfirmation;
verwenden Sie 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.

Das obige ist der detaillierte Inhalt vonWie und wann man Ereignis-Listener in praktischen Codebeispielen von Laravel verwendet. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn