Ereignissystem
Event-System
- Einführung
- Events & Zuhörer registrieren
- Definitionsereignis
- Definitions-Listener
- Ereignis-Listener-Warteschlange
- Events verteilen
- Event-Abonnenten
Einführung in das Eventsystem
Laravel Das Ereignis stellt eine einfache Beobachterimplementierung bereit, die verschiedene in der Anwendung auftretende Ereignisse abonnieren und abhören kann. Ereignisklassen werden normalerweise im Verzeichnis app/Events
gespeichert, und die Listener für diese Ereignisklassen werden im Verzeichnis app/Listeners
gespeichert. Wenn Sie diese Verzeichnisse in Ihrer Anwendung nicht sehen, machen Sie sich keine Sorgen, sie werden automatisch erstellt, wenn Sie Artisan-Konsolenbefehle zum Generieren von Ereignissen und Listenern verwenden.
Das Ereignissystem bietet eine hervorragende Möglichkeit, verschiedene Aspekte der Anwendung zu entkoppeln, da ein einzelnes Ereignis mehrere voneinander unabhängige Listener haben kann. Beispielsweise möchten Sie Ihren Benutzern möglicherweise jedes Mal, wenn eine Bestellung versandt wird, eine Slack-Benachrichtigung senden. Anstatt Ihren Bestellabwicklungscode und den Slack-Benachrichtigungscode miteinander zu verknüpfen, können Sie einfach ein OrderShipped
-Ereignis auslösen, das von einem Listener empfangen und in eine Slack-Benachrichtigung umgewandelt werden kann.
Registrieren von Ereignissen und Zuhörern
EventServiceProvider
in der Laravel-Anwendung bietet die Registrierung aller Ereigniszuhörer einen bequemen Ort. Darunter enthält das Attribut listen
ein Array aller Ereignisse (Schlüssel) und der den Ereignissen entsprechenden Listener (Werte). Natürlich können Sie je nach den Anforderungen Ihrer Anwendung mehrere Ereignisse zum im Attribut listen
enthaltenen Array hinzufügen. Fügen wir zum Beispiel ein OrderShipped
-Ereignis hinzu:
/** * 应用程序的事件监听器映射 * * @var array */ protected $listen = [ 'App\Events\OrderShipped' => [ 'App\Listeners\SendShipmentNotification', ], ];
Ereignisse und Listener generieren
Natürlich ist das manuelle Erstellen von Ereignis- und Listener-Dateien mühsam. Hier müssen Sie lediglich Listener und Ereignisse zu EventServiceProvider
hinzufügen und dann den Befehl event:generate
verwenden. Dieser Befehl generiert alle in EventServiceProvider
aufgeführten Ereignisse und Listener. Selbstverständlich bleiben bereits bestehende Events und Zuhörer unverändert:
php artisan event:generate
Events manuell registrieren
Normalerweise sind Events registriert im EventServiceProvider
-Array von $listen
; Sie können sich jedoch auch in EventServiceProvider
registrieren Registrieren Sie diese abschlussbasierten Ereignisse manuell in der boot
-Methode:
/** * 注册应用中的其它事件 * * @return void */ public function boot(){ parent::boot(); Event::listen('event.name', function ($foo, $bar) { // }); }
Wildcard-Ereignis-Listener
Sie können *
als Wildcard-Parameter verwenden, damit mehrere Ereignisse möglich sind auf demselben Listener erfasst. Ein Platzhalter-Listener erhält als erstes Argument den Ereignisnamen und als zweites Argument das gesamte Ereignisdatenarray:
Event::listen('event.*', function ($eventName, array $data) { // });
Ereignisse definieren
Die Ereignisklasse ist ein Container, der Informationen zum Ereignis speichert. Nehmen wir zum Beispiel an, dass das von uns generierte OrderShipped
-Ereignis ein Eloquent ORM-Objekt empfängt:
<?php namespace App\Events; use App\Order; use Illuminate\Queue\SerializesModels; class OrderShipped{ use SerializesModels; public $order; /** * 创建一个事件实例。 * * @param \App\Order $order * @return void */ public function __construct(Order $order) { $this->order = $order; } }
Wie Sie sehen können, ist in dieser Ereignisklasse keine andere Logik enthalten. Es handelt sich lediglich um einen Container für eine gekaufte Instanz von Order
. Wenn Sie die serialize
-Funktion von PHP verwenden, um ein Ereignisobjekt zu serialisieren, serialisiert das vom Ereignis verwendete Merkmal SerializesModels
jedes Eloquent-Modell ordnungsgemäß.
Listener definieren
Als nächstes schauen wir uns die Listener für die Ereignisse im Beispiel an. Ereignis-Listener empfangen Instanzen in handle
-Methoden. Der Befehl event:generate
lädt automatisch die richtige Ereignisklasse und fügt den Ereignistyphinweis zur Methode handle
hinzu. In der handle
-Methode können Sie alle erforderlichen Aktionen als Reaktion auf das Ereignis ausführen:
<?php namespace App\Listeners; use App\Events\OrderShipped; class SendShipmentNotification{ /** * 创建事件监听器。 * * @return void */ public function __construct() { // } /** * 处理事件。 * * @param \App\Events\OrderShipped $event * @return void */ public function handle(OrderShipped $event) { // 使用 $event->order 来访问 order ... } }
{tip} Ihr Ereignis-Listener kann auch Typhinweise für alle Abhängigkeiten im Konstruktor hinzufügen. Alle Ereignis-Listener werden über den Service-Container von Laravel aufgelöst, sodass alle Abhängigkeiten automatisch eingefügt werden.
Ereignisweitergabe stoppen
Manchmal können Sie die Weitergabe von Ereignissen an andere Listener verhindern, indem Sie handle
in der false
-Methode Get des Listeners zurückgeben.
Ereignis-Listener-Warteschlange
Wenn Ihr Listener eine langsame Aufgabe ausführen muss, z. B. das Senden einer E-Mail oder das Senden einer HTTP-Anfrage, können Sie ihn zur Verarbeitung in die Warteschlange stellen. Bevor Sie mit der Verwendung eines Warteschlangen-Listeners beginnen, stellen Sie sicher, dass Sie Warteschlangen konfigurieren und einen Warteschlangen-Listener auf Ihrem Server oder Ihrer lokalen Entwicklungsumgebung starten können.
Um einen Listener zum Starten der Warteschlange anzugeben, können Sie die ShouldQueue
-Schnittstelle zur Listener-Klasse hinzufügen. Der vom Artisan-Befehl event:generate
generierte Listener hat diese Schnittstelle in den aktuellen Namespace importiert, sodass Sie sie direkt verwenden können:
<?php namespace App\Listeners; use App\Events\OrderShipped; use Illuminate\Contracts\Queue\ShouldQueue; class SendShipmentNotification implements ShouldQueue{ // }
Das ist es! Wenn dieser Listener von einem Ereignis aufgerufen wird, verwendet der Ereignis-Dispatcher automatisch das Warteschlangensystem von Laravel. Wenn beim Ausführen des Listeners in der Warteschlange keine Ausnahme ausgelöst wird, wird die Aufgabe nach Abschluss der Ausführung automatisch aus der Warteschlange gelöscht.
Benutzerdefinierte Warteschlangenverbindung und Warteschlangenname
Wenn Sie die Verbindung und den Namen der vom Ereignis-Listener verwendeten Warteschlange anpassen möchten, können Sie dies in der Listener-Klasse tun Definieren Sie $connection
, $queue
oder $delay
Attribute:
<?php namespace App\Listeners; use App\Events\OrderShipped; use Illuminate\Contracts\Queue\ShouldQueue; class SendShipmentNotification implements ShouldQueue{ /** * The name of the connection the job should be sent to. * * @var string|null */ public $connection = 'sqs'; /** * The name of the queue the job should be sent to. * * @var string|null */ public $queue = 'listeners'; /** * The time (seconds) before the job should be processed. * * @var int */ public $delay = 60; }
Manueller Zugriff auf die Warteschlange
Wenn Sie manuell auf die Warteschlangenaufgabe unter dem Listener zugreifen müssen delete
- und release
-Methoden können Sie dies tun, indem Sie die Eigenschaft IlluminateQueueInteractsWithQueue
verwenden. Diese Eigenschaft wird standardmäßig in den generierten Listener geladen und bietet Zugriff auf diese Methoden:
<?php namespace App\Listeners; use App\Events\OrderShipped; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Contracts\Queue\ShouldQueue; class SendShipmentNotification implements ShouldQueue{ use InteractsWithQueue; /** * 处理事件。 * * @param \App\Events\OrderShipped $event * @return void */ public function handle(OrderShipped $event) { if (true) { $this->release(30); } } }
Behandlung fehlgeschlagener Aufgaben
Manchmal kann die Warteschlangenaufgabe eines Ereignis-Listeners fehlschlagen. Wenn die Warteschlangenaufgaben des Listeners die in der Warteschlange definierte maximale Anzahl von Versuchen überschreiten, wird die Methode failed
auf dem Listener aufgerufen. Die failed
-Methode empfängt eine Ereignisinstanz und die Ausnahme, die den Fehler verursacht hat, als Parameter:
<?php namespace App\Listeners;use App\Events\OrderShipped; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Contracts\Queue\ShouldQueue; class SendShipmentNotification implements ShouldQueue{ use InteractsWithQueue; /** * 处理事件。 * * @param \App\Events\OrderShipped $event * @return void */ public function handle(OrderShipped $event) { // } /** * 处理失败任务。 * * @param \App\Events\OrderShipped $event * @param \Exception $exception * @return void */ public function failed(OrderShipped $event, $exception) { // } }
Versendet das Ereignis
Wenn Sie Ereignisse auslösen möchten, können Sie die Ereignisinstanz an die Hilfsfunktion event
übergeben. Diese Hilfsfunktion verteilt das Ereignis an alle registrierten Listener, die dem Ereignis entsprechen. event
Hilfsfunktionen können global verwendet werden und Sie können sie überall in Ihrer Anwendung aufrufen:
<?php namespace App\Http\Controllers; use App\Order;use App\Events\OrderShipped; use App\Http\Controllers\Controller; class OrderController extends Controller{ /** * 将传递过来的订单发货 * * @param int $orderId * @return Response */ public function ship($orderId) { $order = Order::findOrFail($orderId); // 订单发货逻辑 ... event(new OrderShipped($order)); } }
{tip} Beim Testen müssen Sie nur sicherstellen, dass ein bestimmtes Ereignis ausgelöst wird, ohne das tatsächlich auszulösen Hörer. Die integrierten Testhelfer von Laravel machen dies einfach.
Event-Abonnent
Ereignisabonnenten schreiben
Ereignisabonnenten sind Klassen, die mehrere Ereignisse in sich selbst abonnieren können, das heißt, sie können mehrere Ereignishandler in einer einzigen Klasse definieren. Abonnenten sollten eine subscribe
-Methode definieren, die eine Event-Dispatcher-Instanz empfängt. Sie können Ereignis-Listener registrieren, indem Sie die Methode listen
für einen bestimmten Ereignis-Dispatcher aufrufen:
<?php namespace App\Listeners; class UserEventSubscriber{ /** * 处理用户登录事件。 */ public function onUserLogin($event) {} /** * 处理用户注销事件。 */ public function onUserLogout($event) {} /** * 为订阅者注册监听器 * * @param \Illuminate\Events\Dispatcher $events */ public function subscribe($events) { $events->listen( 'Illuminate\Auth\Events\Login', 'App\Listeners\UserEventSubscriber@onUserLogin' ); $events->listen( 'Illuminate\Auth\Events\Logout', 'App\Listeners\UserEventSubscriber@onUserLogout' ); } }
Register Event Subscriber
Nachdem Sie den Abonnenten geschrieben haben, können Sie den Abonnenten über den Event-Dispatcher registrieren. Sie können Abonnenten im EventServiceProvider
-Attribut innerhalb von $subscribe
registrieren. Fügen wir beispielsweise UserEventSubscriber
zu einer Array-Liste hinzu:
<?php namespace App\Providers; use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider; class EventServiceProvider extends ServiceProvider{ /** * 应用中事件监听器的映射。 * * @var array */ protected $listen = [ // ]; /** * 需要注册的订阅者类。 * * @var array */ protected $subscribe = [ 'App\Listeners\UserEventSubscriber', ]; }