Heim >Backend-Entwicklung >PHP-Tutorial >Ein Leitfaden zu Laravels Modellereignissen

Ein Leitfaden zu Laravels Modellereignissen

James Robert Taylor
James Robert TaylorOriginal
2025-03-06 02:25:14852Durchsuche

A guide to Laravel's model events

Die Modellereignisse von

Laravel sind eine sehr bequeme Funktion, mit der Sie bei der Durchführung bestimmter Vorgänge auf Ihrem beredten Modell automatisch Logik ausführen können. Wenn dies jedoch nicht ordnungsgemäß verwendet wird, kann dies manchmal zu seltsamen Nebenwirkungen führen.

In diesem Artikel wird untersucht, welche Modellereignisse sie sind und wie sie in Laravel -Anwendungen verwendet werden. Wir werden auch untersuchen, wie Sie Modellereignisse und einige Probleme testen, die Sie bei der Verwendung bewusst sind. Schließlich werden wir einige Alternativen zu Modellereignissen abdecken, die Sie in Betracht ziehen können.

Was sind Ereignisse und Zuhörer?


Sie haben vielleicht von "Ereignissen" und "Zuhörern" gehört. Aber wenn Sie noch nicht davon gehört haben, finden Sie hier einen kurzen Überblick darüber:

#event

Dies ist das, was in den Apps passiert, auf die Sie reagieren möchten - beispielsweise haben Benutzer sich auf Ihrer Website anmelden, Benutzer melden sich an usw.

In Laravel sind Ereignisse normalerweise PHP -Klassen. Zusätzlich zu den Ereignissen, die von Frameworks oder Drittanbieterpaketen bereitgestellt werden, werden sie normalerweise im Verzeichnis app/Events gespeichert.

Folgendes ist ein Beispiel für eine einfache Ereignisklasse, die Sie möglicherweise planen möchten, wenn ein Benutzer auf Ihre Website registriert:

declare(strict_types=1);

namespace App\Events;

use App\Models\User;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

final class UserRegistered
{
    use Dispatchable;
    use InteractsWithSockets;
    use SerializesModels;

    public function __construct(public User $user)
    {
        //
    }
}

Im obigen grundlegenden Beispiel haben wir eine AppEventsUserRegistered Ereignisklasse, die eine User -Modellinstanz in seinem Konstruktor akzeptiert. Diese Ereignisklasse ist ein einfacher Container zum Speichern registrierter Benutzerinstanzen.

Beim Versand auslöst das Ereignis jeden Hörer, der es hört.

Folgendes ist ein einfaches Beispiel für die Planung des Ereignisses, wenn ein Benutzer registriert:

use App\Events\UserRegistered;
use App\Models\User;

$user = User::create([
    'name' => 'Eric Barnes',
    'email' => 'eric@example.com',
]);

UserRegistered::dispatch($user);
Im obigen Beispiel erstellen wir einen neuen Benutzer und planen dann das Ereignis

mit der Benutzerinstanz. Angenommen, der Hörer ist korrekt registriert, löst dies jeden Hörer aus, der das Ereignis AppEventsUserRegistered hört. AppEventsUserRegistered

#Listener

Hörer sind Codeblöcke, die Sie ausführen möchten, wenn ein bestimmtes Ereignis auftritt.

Bleiben Sie beispielsweise bei unserem Benutzerregistrierungsbeispiel. Möglicherweise möchten Sie eine willkommene E -Mail an den Benutzer senden, wenn sich der Benutzer registriert. Sie können einen Hörer für die

-Veranstaltung erstellen und eine willkommene E -Mail senden. AppEventsUserRegistered

In Laravel sind die Zuhörer normalerweise (aber nicht immer) Klassen im Verzeichnis

. app/Listeners

Beispiel dafür, dass der Hörer eine willkommene E -Mail an einen Benutzer sendet, wenn ein Benutzerregister so aussieht:

declare(strict_types=1);

namespace App\Listeners;

use App\Events\UserRegistered;
use App\Notifications\WelcomeNotification;
use Illuminate\Support\Facades\Mail;

final readonly class SendWelcomeEmail
{
    public function handle(UserRegistered $event): void
    {
        $event->user->notify(new WelcomeNotification());
    }
}
Wie wir im obigen Codebeispiel gesehen haben, hat die

-Listener -Klasse eine AppListenersSendWelcomeEmail -Methode, die eine handle -Ereigungsinstanz akzeptiert. Diese Methode ist für das Senden einer willkommenen E -Mail an den Benutzer verantwortlich. AppEventsUserRegistered

Für eingehende Anweisungen zu Ereignissen und Hörern möchten Sie sich möglicherweise die offizielle Dokumentation ansehen: https://www.php.cn/link/d9a8c56824cfbe6f28f85edbbe83E09

Was ist ein Modellereignis?

In Ihrer Laravel -Anwendung müssen Sie in der Regel Ereignisse manuell planen, wenn bestimmte Aktionen auftreten. Wie wir im obigen Beispiel gesehen haben, können wir Ereignisse mit dem folgenden Code planen:
declare(strict_types=1);

namespace App\Events;

use App\Models\User;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

final class UserRegistered
{
    use Dispatchable;
    use InteractsWithSockets;
    use SerializesModels;

    public function __construct(public User $user)
    {
        //
    }
}

Bei Verwendung des beredten Modells in Laravel sind einige Ereignisse für uns automatisch geplant, sodass wir sie nicht manuell planen müssen. Wenn wir bei Ereignissen Operationen ausführen möchten, müssen wir nur die Zuhörer für sie definieren.

Die folgende Liste zeigt Ereignisse und Auslöser, die automatisch vom eloquenten Modell geplant sind:
  • abgerufen - Abnehmen aus der Datenbank.
  • Erstellen - Erstellen eines Modells.
  • Erstellt - Das Modell wurde erstellt.
  • Aktualisieren - Aktualisieren des Modells.
  • aktualisiert - Das Modell wurde aktualisiert.
  • Speichern - Erstellen oder Aktualisieren eines Modells.
  • gespeichert - Das Modell wurde erstellt oder aktualisiert.
  • Löschen - Löschen des Modells.
  • gelöscht - Das Modell wurde gelöscht.
  • Müll - Das Modell wurde sanft gelöscht.
  • erzwungenes Handeln - Erzwungene Löschung des Modells.
  • erzwungen - das Modell wurde gezwungen,
  • gelöscht zu werden
  • Wiederherstellung - Wiederherstellen des Modells aus der weichen Löschung.
  • restauriert - Das Modell wurde aus Soft Delete wiederhergestellt.
  • replizieren - Replikation des Modells.

creating In der obigen Liste können Sie einige Ereignisnamen ähnlich bemerken; Ereignisse, die mit created enden, werden vor dem Vorgang ausgeführt, und die Änderungen werden in der Datenbank bestehen. Ereignisse, die mit ing enden, werden nach dem Vorgang ausgeführt, und die Änderungen werden in der Datenbank bestehen. ed

Lassen Sie uns sehen, wie diese Modellereignisse in einer Laravel -Anwendung verwendet werden.

Verwenden Sie

Modell Ereignisse dispatchesEvents


Eine Möglichkeit, auf Modellereignisse zuzuhören, besteht darin, eine

-Mobilie auf Ihrem Modell zu definieren. dispatchesEvents

Mit dieser Eigenschaft können Sie eloquente Modellereignisse in die Ereignisklasse zuordnen, die bei der Aufführung des Ereignisses geplant werden sollte. Dies bedeutet, dass Sie den Hörer so definieren können, wie Sie es für jedes andere Ereignis verarbeiten würden.

Um mehr Kontext bereitzustellen, schauen wir uns ein Beispiel an.

Angenommen, wir erstellen eine Blog -Anwendung mit zwei Modellen:

und AppModelsPost. Wir werden sagen, dass beide Modelle eine weiche Löschung unterstützen. Wenn wir ein neues AppModelsAuthor speichern, möchten wir die Lesezeit des Artikels basierend auf der Länge des Inhalts berechnen. Wenn wir den Autor sanft löschen, möchten wir, dass der Autor alle Artikel sanft löscht. AppModelsPost

#Set das Modell

wir können ein

Modell haben, wie unten gezeigt: AppModelsAuthor

use App\Events\UserRegistered;
use App\Models\User;

$user = User::create([
    'name' => 'Eric Barnes',
    'email' => 'eric@example.com',
]);

UserRegistered::dispatch($user);
Im obigen Modell haben wir:

  • addierte eine dispatchesEvents -Mobilie hinzu, die das deleted -Modellereignis der Ereignisklasse AppEventsAuthorDeleted ordnet. Dies bedeutet, dass beim Löschen des Modells ein neues AppEventsAuthorDeleted -Ereignis geplant wird. Wir werden diese Ereignisklasse später erstellen.
  • definiert eine posts -Beziehung.
  • Die weiche Löschung
  • wird auf dem Modell mithilfe der Funktion IlluminateDatabaseEloquentSoftDeletes aktiviert.

Erstellen wir unser AppModelsPost Modell:

declare(strict_types=1);

namespace App\Events;

use App\Models\User;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

final class UserRegistered
{
    use Dispatchable;
    use InteractsWithSockets;
    use SerializesModels;

    public function __construct(public User $user)
    {
        //
    }
}

im obigen AppModelsPost Modell haben wir:

  • addierte eine dispatchesEvents -Mobilie hinzu, die das saving -Modellereignis der Ereignisklasse AppEventsPostSaving ordnet. Dies bedeutet, dass beim Erstellen oder Aktualisieren des Modells ein neues AppEventsPostSaving -Ereignis geplant wird. Wir werden diese Ereignisklasse später erstellen.
  • definiert eine author -Beziehung.
  • Die weiche Löschung
  • wird auf dem Modell mithilfe der Funktion IlluminateDatabaseEloquentSoftDeletes aktiviert.

Unser Modell ist jetzt bereit, also erstellen wir unsere Ereignisklassen AppEventsAuthorDeleted und AppEventsPostSaving.

#create Ereignisklasse

Wir erstellen eine AppEventsPostSaving Ereignisklasse, die beim Speichern eines neuen Artikels geplant ist:

use App\Events\UserRegistered;
use App\Models\User;

$user = User::create([
    'name' => 'Eric Barnes',
    'email' => 'eric@example.com',
]);

UserRegistered::dispatch($user);

Im obigen Code können wir die Ereignisklasse AppEventsPostSaving sehen, die eine AppModelsPost -Modellinstanz in seinem Konstruktor akzeptiert. Diese Ereignisklasse ist ein einfacher Container zum Speichern der zu speichernden Artikelinstanz.

In ähnlicher Weise können wir eine AppEventsAuthorDeleted Ereignisklasse erstellen, die beim Löschen des Autors geplant ist:

declare(strict_types=1);

namespace App\Listeners;

use App\Events\UserRegistered;
use App\Notifications\WelcomeNotification;
use Illuminate\Support\Facades\Mail;

final readonly class SendWelcomeEmail
{
    public function handle(UserRegistered $event): void
    {
        $event->user->notify(new WelcomeNotification());
    }
}

In der obigen AppEventsAuthorDeleted -Klass können wir sehen, dass der Konstruktor eine AppModelsAuthor Modellinstanz akzeptiert.

Jetzt können wir weiterhin Zuhörer erstellen.

#create louser

Lassen Sie uns zunächst einen Hörer erstellen, mit dem die Schätzung der Lesezeit des Artikels berechnet werden kann.

Wir werden eine neue AppListenersCalculateReadTime Hörerklasse erstellen:

UserRegistered::dispatch($user);

Wie wir im obigen Code sehen, haben wir nur eine handle -Methode. Dies ist eine Methode, die beim Planen des AppEventsPostSaving -Ergners automatisch aufgerufen wird. Es akzeptiert eine Instanz der Ereignisklasse AppEventsPostSaving, die den zu speichernden Artikel enthält.

In der Methode handle verwenden wir eine einfache Formel, um die Lesezeit des Artikels zu berechnen. In diesem Beispiel gehen wir davon aus, dass die durchschnittliche Lesegeschwindigkeit 265 Wörter pro Minute beträgt. Wir berechnen die Lesezeit in Sekunden und setzen dann das read_time_in_seconds -Merkmal im Artikelmodell ein.

Da dieser Hörer aufgerufen wird, wenn das Modell saving Modell ausgelöst wird, bedeutet dies, dass das Attribut read_time_in_seconds jedes Mal berechnet wird, wenn der Artikel vor dem Erstellen oder Aktualisieren in der Datenbank bestehen wird.

Wir können auch einen Hörer erstellen, der alle verwandten Artikel sanft löscht, wenn der Autor sanft löscht.

Wir können eine neue AppListenersSoftDeleteAuthorRelationships Hörerklasse erstellen:

declare(strict_types=1);

namespace App\Events;

use App\Models\User;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

final class UserRegistered
{
    use Dispatchable;
    use InteractsWithSockets;
    use SerializesModels;

    public function __construct(public User $user)
    {
        //
    }
}

Im obigen Hörer akzeptiert die handle -Methode eine Instanz der Ereignisklasse AppEventsAuthorDeleted. Diese Ereignisklasse enthält, dass der Autor gelöscht wird. Anschließend verwenden wir die posts -Beziehung, um den Artikel des Autors zu löschen. delete

Daher werden alle Artikel der Autoren, wenn das Modell

sanft gelöscht wird, ebenfalls sanft gelöscht. AppModelsAuthor

Es ist übrigens erwähnenswert, dass Sie möglicherweise eine leistungsstärkere, wiederverwendbare Lösung verwenden möchten, um dies zu erreichen. Aber für die Zwecke dieses Artikels halten wir es einfach.

Verwenden Sie den Verschluss, um auf Modellereignisse zu hören


Eine andere Möglichkeit, den Hörer als Schließung des Modells selbst zu definieren.

Schauen wir uns das Beispiel für weiche Löschartikel an, wenn wir den Autor sanft gelöscht haben. Wir können unser

-Modell aktualisieren, um einen Verschluss zu enthalten, der für AppModelsAuthor Modellereignisse hört: deleted

use App\Events\UserRegistered;
use App\Models\User;

$user = User::create([
    'name' => 'Eric Barnes',
    'email' => 'eric@example.com',
]);

UserRegistered::dispatch($user);
wir können im obigen Modell sehen, dass wir den Hörer in der

-Methode des Modells definieren. Wir möchten auf das booted Modellereignis zuhören, also haben wir deleted verwendet. In ähnlicher Weise können wir self::deleted usw. verwenden, wenn wir einen Hörer für das created -Modellereignis erstellen möchten. Die self::created -Methode akzeptiert einen Verschluss, der das gelöschte self::deleted erhält. Diese Schließung wird ausgeführt, wenn das Modell gelöscht wird, sodass alle Autorenartikel gelöscht werden. AppModelsAuthor

Ich mag diese Art, die Logik der Hörer zu definieren, wirklich, da sie sofort sehen kann, ob es einen Beobachter beim Öffnen der Modellklasse registriert. Während die Logik in einer separaten Datei immer noch "versteckt" ist, können wir wissen, dass wir die Hörer für mindestens ein Ereignis des Modells registriert haben. Wenn der Code in diesen Schließungen jedoch komplexer wird, kann es sich lohnt, die Logik in eine separate Hörerklasse zu extrahieren.

Ein praktischer Trick ist, dass Sie auch die Funktion

verwenden können, um die Schließungen in der Warteschlange zu bringen. Dies bedeutet, dass der Code des Hörers in die Warteschlange gedrängt wird, um im Hintergrund zu laufen, und nicht im gleichen Anfrage -Lebenszyklus. Wir können den Hörer wie folgt auf Warteschlangen aktualisieren: IlluminateEventsqueueable

declare(strict_types=1);

namespace App\Listeners;

use App\Events\UserRegistered;
use App\Notifications\WelcomeNotification;
use Illuminate\Support\Facades\Mail;

final readonly class SendWelcomeEmail
{
    public function handle(UserRegistered $event): void
    {
        $event->user->notify(new WelcomeNotification());
    }
}
Wie wir im obigen Beispiel gesehen haben, wickeln wir den Verschluss in die

-Funktion ein. IlluminateEventsqueueable

Verwenden Sie den Beobachter, um auf Modellereignisse zu hören


Eine andere Möglichkeit, wie Sie auf Modellereignisse anhören können, besteht darin, Modellbeobachter zu verwenden. Mit Modellbeobachtern können Sie alle Zuhörer für das Modell in einer Klasse definieren.

Normalerweise sind es Klassen, die im Verzeichnis app/Observers vorhanden sind, und sie haben Methoden, die den Modellereignissen entsprechen, die Sie hören möchten. Wenn Sie beispielsweise auf ein deleted -Modellereignis zuhören möchten, definieren Sie eine deleted -Methode in der Beobachterklasse. Wenn Sie auf ein created Modellereignis zuhören möchten, definieren Sie eine created -Methode in der Beobachterklasse und so weiter.

Lassen Sie uns sehen, wie Sie einen Modellbeobachter für unser AppModelsAuthor Modellhören für deleted Modellereignisse erstellen:

declare(strict_types=1);

namespace App\Events;

use App\Models\User;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

final class UserRegistered
{
    use Dispatchable;
    use InteractsWithSockets;
    use SerializesModels;

    public function __construct(public User $user)
    {
        //
    }
}

Wie wir im obigen Code sehen, erstellen wir einen Beobachter mit der deleted -Methode. Diese Methode akzeptiert Instanzen des gelöschten AppModelsAuthor -Modells. Anschließend verwenden wir die posts -Beziehung, um den Artikel des Autors zu löschen. delete

Angenommen, wir möchten zum Beispiel auch Zuhörer für

und created Modellereignisse definieren. Wir können unsere Beobachter wie folgt aktualisieren: updated

use App\Events\UserRegistered;
use App\Models\User;

$user = User::create([
    'name' => 'Eric Barnes',
    'email' => 'eric@example.com',
]);

UserRegistered::dispatch($user);
Um die

-Methode auszuführen, müssen wir Laravel anweisen, sie zu verwenden. Dazu können wir das AppObserversAuthorObserver -Merkmal verwenden. Dies ermöglicht es uns, Beobachter mit dem Modell zu assoziieren, ähnlich wie bei der Registrierung globaler Abfragebereiche mithilfe des #[IlluminateDatabaseEloquentAttributesObservedBy] -attributs (wie gezeigt, wie das Abfragebuch in Laravel beherrscht). Wir können unser #[ScopedBy] -Modell wie dieses aktualisieren, um den Beobachter zu verwenden: AppModelsAuthor

declare(strict_types=1);

namespace App\Listeners;

use App\Events\UserRegistered;
use App\Notifications\WelcomeNotification;
use Illuminate\Support\Facades\Mail;

final readonly class SendWelcomeEmail
{
    public function handle(UserRegistered $event): void
    {
        $event->user->notify(new WelcomeNotification());
    }
}
Ich mag diese Art, die Logik der Hörer zu definieren, sehr, da sie sofort sehen kann, ob es einen Beobachter beim Öffnen der Modellklasse registriert. Während die Logik in einer separaten Datei immer noch "versteckt" ist, können wir wissen, dass wir die Hörer für mindestens ein Ereignis des Modells registriert haben.

Testen Sie Ihr Modellereignis


Unabhängig davon, welche Modellereignismethode Sie verwenden, möchten Sie möglicherweise einige Tests schreiben, um sicherzustellen, dass Ihre Logik wie erwartet funktioniert.

Lassen Sie uns sehen, wie die Modellereignisse, die wir im obigen Beispiel erstellt haben, testen.

Wir schreiben zuerst einen Test, um sicherzustellen, dass der Artikel des Autors sanft gelöscht wird, wenn der Autor sanft gelöscht wird. Der Test könnte so aussehen:

UserRegistered::dispatch($user);
Im obigen Test erstellen wir einen neuen Autor und Artikel für diesen Autor. Wir haben dann den Autor leise gelöscht und behauptet, dass sowohl der Autor als auch der Artikel sanft gelöscht wurden.

Dies ist ein sehr einfacher, aber effektiver Test, mit dem wir sicherstellen können, dass unsere Logik wie erwartet funktioniert. Der Vorteil dieses Tests besteht darin, dass er mit jeder der in diesem Artikel diskutierten Methoden funktionieren sollte. Wenn Sie also zwischen einer der in diesem Artikel diskutierten Methoden wechseln, sollte Ihr Test noch bestehen.

In ähnlicher Weise können wir einige Tests schreiben, um sicherzustellen, dass die Lesezeit des Artikels beim Erstellen oder Aktualisieren berechnet wird. Der Test könnte so aussehen:

declare(strict_types=1);

namespace App\Events;

use App\Models\User;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

final class UserRegistered
{
    use Dispatchable;
    use InteractsWithSockets;
    use SerializesModels;

    public function __construct(public User $user)
    {
        //
    }
}

Wir haben zwei Tests darauf:

  • Der erste Test stellt sicher, dass die Lesezeit des Artikels beim Erstellen berechnet wird.
  • Der zweite Test stellt sicher, dass die Lesezeit des Artikels berechnet wird, wenn der Artikel aktualisiert wird.

Vorsichtsmaßnahmen bei der Verwendung von Modellereignissen


Obwohl Modellereignisse sehr bequem sind, müssen einige Probleme bei der Verwendung bewusst sein.

Modellereignisse stammen nur aus dem eloquenten Modell. Dies bedeutet, dass ihre Ereignisse nicht geplant sind, wenn Sie IlluminateSupportFacadesDB Fassade verwenden, um mit den zugrunde liegenden Daten des Modells in der Datenbank zu interagieren.

Schauen wir uns beispielsweise ein einfaches Beispiel an, wir verwenden IlluminateSupportFacadesDB Fassade, um den Autor zu löschen:

use App\Events\UserRegistered;
use App\Models\User;

$user = User::create([
    'name' => 'Eric Barnes',
    'email' => 'eric@example.com',
]);

UserRegistered::dispatch($user);

Ausführen des oben genannten Codes löscht den Autor wie erwartet aus der Datenbank. Die Modellereignisse deleting und deleted sind jedoch nicht geplant. Wenn Sie also Hörer für diese Modellereignisse definieren, wenn Sie den Autor löschen, werden sie nicht ausgeführt.

In ähnlicher Weise sind für die betroffenen Modelle die saved, updated, deleting und deleted Modellereignisse nicht geplant. Dies liegt daran, dass Ereignisse aus dem Modell selbst geplant sind. Wenn jedoch Batch -Updates und -Löser aktualisiert werden, wird das Modell nicht tatsächlich aus der Datenbank abgerufen, sodass Ereignisse nicht geplant sind.

Angenommen, wir verwenden den folgenden Code, um den Autor zu löschen:

declare(strict_types=1);

namespace App\Listeners;

use App\Events\UserRegistered;
use App\Notifications\WelcomeNotification;
use Illuminate\Support\Facades\Mail;

final readonly class SendWelcomeEmail
{
    public function handle(UserRegistered $event): void
    {
        $event->user->notify(new WelcomeNotification());
    }
}

Da die Methode delete direkt im Abfragebauer aufgerufen wird, sind die Modellereignisse deleting und deleted für diesen Autor nicht geplant.

Alternative Methoden zur Betrachtung


Ich benutze Modellereignisse in meinen Projekten gerne. Sie dienen als eine gute Möglichkeit, meinen Code zu entkoppeln und es mir auch ermöglichen, die Logik automatisch auszuführen, wenn ich nicht viel Kontrolle über den Code habe, der das Modell betrifft. Wenn ich beispielsweise den Autor in Laravel Nova lösche, kann ich beim Löschen des Autors immer noch eine Logik ausführen.

Es ist jedoch wichtig zu wissen, wann man verschiedene Methoden angewendet hat.

Um dies zu erklären, schauen wir uns ein grundlegendes Beispiel an, in dem wir möglicherweise Modellereignisse vermeiden möchten. Erweitern Sie unser vorheriges Beispiel für einfache Blog -Anwendungen, vorausgesetzt, wir möchten beim Erstellen eines neuen Beitrags Folgendes ausführen:

  • Berechnen Sie die Lesezeit des Artikels.
  • API -Anrufe an X/Twitter senden, um den Artikel zu teilen.
  • Benachrichtigungen an jeden Abonnenten auf der Plattform senden.

Sie können also drei separate Hörer (eine für jede Aufgabe) erstellen, die jedes Mal ausgeführt werden, wenn eine neue AppModelsPost -Stanz erstellt wird.

Aber jetzt lasst uns einen unserer vorherigen Tests überprüfen:

declare(strict_types=1);

namespace App\Events;

use App\Models\User;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

final class UserRegistered
{
    use Dispatchable;
    use InteractsWithSockets;
    use SerializesModels;

    public function __construct(public User $user)
    {
        //
    }
}

Wenn wir den obigen Test ausführen, löst er diese drei Vorgänge auch aus, wenn das AppModelsPost -Modell über seine Fabrik erstellt wird. Natürlich ist die Berechnung der Lesezeit eine sekundäre Aufgabe, daher spielt es keine Rolle. Wir möchten jedoch nicht versuchen, API -Anrufe zu tätigen oder Benachrichtigungen während des Tests zu senden. Dies sind unerwartete Nebenwirkungen. Wenn der Entwickler, der den Test schrieb, diese Nebenwirkungen nicht bekannt ist, kann es schwierig sein, herauszufinden, warum diese Vorgänge auftreten.

Wir möchten auch vermeiden, dass eine testspezifische Logik im Hörer geschrieben wird, was verhindert, dass diese Operationen während der Tests ausgeführt werden. Dadurch wird der Anwendungscode komplexer und gewartet.

Dies ist einer der Fälle, in denen Sie einen expliziteren Ansatz in Betracht ziehen möchten, anstatt sich auf automatische Modellereignisse zu verlassen.

Eine Möglichkeit kann darin bestehen, Ihren Erstellungscode AppModelsPost in einen Dienst oder eine Aktionsklasse zu extrahieren. Zum Beispiel könnte eine einfache Dienstklasse so aussehen:

use App\Events\UserRegistered;
use App\Models\User;

$user = User::create([
    'name' => 'Eric Barnes',
    'email' => 'eric@example.com',
]);

UserRegistered::dispatch($user);

In der obigen Klasse rufen wir den Code manuell auf, der die Lesezeit berechnet, Benachrichtigungen und Beiträge an Twitter sendet. Dies bedeutet, dass wir eine bessere Kontrolle darüber haben, wenn diese Operationen ausgeführt werden. Wir können diese Methoden auch in Tests auch leicht verspotten, um zu verhindern, dass sie laufen. Wir können diese Operationen bei Bedarf immer noch anstellen (in diesem Fall werden wir dies höchstwahrscheinlich tun).

Daher können wir die Modellereignisse und Zuhörer für diese Operationen löschen. Dies bedeutet, dass wir diese neue AppServicesPostService -Klasse in unserem Anwendungscode verwenden und die Modellfabrik in unserem Testcode sicher verwenden können.

Der zusätzliche Vorteil davon ist, dass der Code auch das Verständnis erleichtert. Wie ich kurz erwähnte, ist eine häufige Kritik an der Verwendung von Ereignissen und Zuhörern, dass sie die Geschäftslogik an unerwarteten Orten verbergen kann. Wenn also neue Entwickler dem Team beitreten und durch Modellereignisse ausgelöst werden, wissen sie möglicherweise nicht, wo oder warum einige Operationen eintreten.

Wenn Sie jedoch noch Ereignisse und Hörer für eine solche Logik verwenden möchten, können Sie einen expliziteren Ansatz verwenden. Sie können beispielsweise ein Ereignis aus der Serviceklasse planen, um den Hörer auszulösen. Auf diese Weise können Sie immer noch die Entkopplungsvorteile von Ereignissen und Zuhörern nutzen, aber Sie haben eine bessere Kontrolle darüber, wenn Ereignisse geplant sind.

Zum Beispiel können wir die obige AppServicesPostService -Methode in unserem createPost -Albile aktualisieren, um Ereignisse zu planen:

declare(strict_types=1);

namespace App\Listeners;

use App\Events\UserRegistered;
use App\Notifications\WelcomeNotification;
use Illuminate\Support\Facades\Mail;

final readonly class SendWelcomeEmail
{
    public function handle(UserRegistered $event): void
    {
        $event->user->notify(new WelcomeNotification());
    }
}

Mit der obigen Methode können wir immer noch einen separaten Hörer haben, um API -Anfragen zu stellen und Benachrichtigungen an Twitter zu senden. Wir haben jedoch eine bessere Kontrolle darüber, wenn diese Operationen ausgeführt werden, sodass sie beim Testen mithilfe der Modellfabrik nicht ausgeführt werden.

Es gibt keine goldene Regel bei der Entscheidung, eine dieser Methoden zu verwenden. Es hängt alles von Ihnen, Ihrem Team und den Funktionen ab, die Sie bauen. Ich neige jedoch dazu, die folgenden Faustregeln zu befolgen:

  • Wenn die Operationen im Hörer nur geringfügige Änderungen des Modells vornehmen, sollten Sie Modellereignisse verwenden. Beispiel: Schnecken generieren, Lesezeit berechnen usw.
  • Wenn sich der Vorgang auf ein anderes Modell auswirkt (unabhängig davon, ob es automatisch erstellt, aktualisiert oder gelöscht wird), ist es klarer und verwenden keine Modellereignisse.
  • Wenn der Vorgang mit externen Prozessen (API -Aufrufe, Dateiverarbeitung, Triggerbenachrichtigungen, in der Warteschleife) gearbeitet wird, ist klarer, dass Sie keine Modellereignisse verwenden.

Vor- und Nachteile der Verwendung von Modellereignissen


Um schnell zusammenzufassen, was wir in diesem Artikel eingeführt haben, finden Sie hier einige der Vor- und Nachteile der Verwendung von Modellereignissen:

#Pros

  • Ermutigen Sie, den Code zu entkoppeln.
  • Mit
  • können Sie Aktionen automatisch auslösen, unabhängig davon, wo das Modell erstellt/aktualisiert/löschen wird. Wenn das Modell beispielsweise in Laravel Nova erstellt wurde, können Sie die Geschäftslogik auslösen.
  • Sie müssen sich nicht daran erinnern, Ereignisse jedes Mal zu planen, wenn Sie ein Modell erstellen/aktualisieren/löschen.

#disadVantages

  • kann unerwartete Nebenwirkungen verursachen. Möglicherweise möchten Sie das Modell erstellen/aktualisieren/löschen, ohne einige Zuhörer auszulösen. Dies kann jedoch zu unerwartetem Verhalten führen. Dies ist besonders beim Schreiben von Tests problematisch.
  • Geschäftslogik kann an unerwarteten Orten versteckt sein, die schwer zu verfolgen sind. Dadurch wird der Code schwieriger zu verstehen.

Schlussfolgerung


Ich hoffe, dieser Artikel bietet einen Überblick darüber, welche Modellereignisse und die verschiedenen Möglichkeiten, sie zu verwenden,. Es sollte Ihnen auch zeigen, wie Sie Modellereigniscodes und einige Probleme testen, die Sie bei der Verwendung bewusst sind.

Sie sollten jetzt genug Vertrauen haben, um Modellereignisse in Ihrer Laravel -Anwendung zu verwenden.

Das obige ist der detaillierte Inhalt vonEin Leitfaden zu Laravels Modellereignissen. 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
Vorheriger Artikel:API -Versioning in Laravel 11Nächster Artikel:API -Versioning in Laravel 11