Detaillierte Erläuterung der Schritte zur Implementierung von Laravel-Modellereignissen

php中世界最好的语言
Freigeben: 2023-03-26 14:16:01
Original
2020 Leute haben es durchsucht

Dieses Mal werde ich Ihnen die Schritte zur Implementierung von Laravel-Modellereignissen ausführlich erläutern. Was sind die Vorsichtsmaßnahmen für die Implementierung von Laravel-Modellereignissen?

Vorwort

Das ORM-Modell von Laravel löst unter bestimmten Umständen eine Reihe von Ereignissen aus: Erstellen, Erstellt, Aktualisieren, Aktualisieren, Speichern, Speichern, Löschen, Löschen, Wiederherstellen, Wiederherstellen. Wie wird diese Funktion auf der untersten Ebene implementiert?

Im Folgenden gibt es nicht viel zu sagen, werfen wir einen Blick auf die ausführliche Einführung.

1. So verwenden Sie Modellereignisse

Schauen wir uns zunächst an, wie Sie Modellereignisse verwenden Tatsächlich gibt es insgesamt drei Möglichkeiten, ein Modellereignis zu definieren. Hier nehmen wir das gespeicherte Ereignis und die anderen Ereignisse sind gleich.

1.events-Attribut

Direkter Code:

class User extends Authenticatable {
 use Notifiable;
 protected $events = [
  'saved' => UserSaved::class,
 ];
}
Nach dem Login kopieren

Das ist schwer zu verstehen und wird im Dokument zunächst nicht im Detail erklärt Ich dachte, dass „saved“ war. Nach dem Auslösen wird die Handle-Methode in „UserSaved“ aufgerufen, aber das ist nicht wirklich der Fall. Dieses Array ist nur eine Zuordnung von Ereignissen. Es definiert, dass das UserSaved-Ereignis ausgelöst wird, wenn das Modell gespeichert wird. Wir müssen auch das Ereignis und seinen Listener definieren:

namespace App\Events;
use App\User;
class UserSaved {
 public $user;
 public function construct(User $user){
  $this->user = $user;
 }
}
Nach dem Login kopieren
rreee

und dann zum EventServiceProvider gehen Ereignis und Listener:

namespace App\Listeners;
class UserSavedListener {
 public function handle(UserSaved $userSaved){
  dd($userSaved);
 }
}
Nach dem Login kopieren

Auf diese Weise wird beim Speichern des gespeicherten Knotens das UserSaved-Ereignis ausgelöst und die Handle-Methode seines Listeners UserSavedListener aufgerufen.

2. Beobachter

Dies ist eine vom Dokument empfohlene Methode zur Definition von Modellereignissen, die einfacher zu verstehen ist. Definieren Sie zunächst einen Beobachter:

class EventServiceProvider extends ServiceProvider
{
 /**
  * The event listener mappings for the application.
  *
  * @var array
  */
 protected $listen = [
  'App\Events\UserSaved' => [
   'App\Listeners\UserSavedListener',
  ]
 ];
 /**
  * Register any events for your application.
  *
  * @return void
  */
 public function boot()
 {
  parent::boot();
 }
}
Nach dem Login kopieren

Dann registrieren Sie den Beobachter in der Boot-Methode eines Dienstanbieters:

use App\User;
class UserObserver
{
 /**
  * 监听用户创建事件.
  *
  * @param User $user
  * @return void
  */
 public function created(User $user)
 {
  //
 }
 /**
  * 监听用户创建/更新事件.
  *
  * @param User $user
  * @return void
  */
 public function saved(User $user)
 {
  //
 }
}
Nach dem Login kopieren

Auf diese Weise wird beim Auslösen des Modellereignisses die entsprechende Methode von UserObserver aufgerufen. Tatsächlich können wir bei der Verwendung von Beobachtern zusätzlich zu einigen der mit dem System gelieferten auch einige unserer eigenen Ereignisse definieren:

namespace App\Providers;
use App\User;
use App\Observers\UserObserver;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
 /**
  * Bootstrap any application services.
  *
  * @return void
  */
 public function boot()
 {
  User::observe(UserObserver::class);
 }
 /**
  * Register the service provider.
  *
  * @return void
  */
 public function register()
 {
  //
 }
}
Nach dem Login kopieren

Definieren Sie dann eine Methode mit demselben Namen im Beobachter:

class User extends Authenticatable {
 use Notifiable;
 protected $observables = [
  'customing', 'customed'
 ];
}
Nach dem Login kopieren

Weil wir Ereignisse selbst definieren, müssen sie manuell ausgelöst werden. Rufen Sie einfach eine fireModelEvent-Methode im Modell auf, wo sie ausgelöst werden muss. Da diese Methode jedoch geschützt ist, kann sie nur in der von Ihnen definierten Modellmethode verwendet werden. Wenn sie über Reflektion aufgerufen wird, kann sie natürlich nicht direkt auf dem $user-Objekt ausgelöst werden kann es selbst testen.

class UserObserver
{
 /**
  * 监听用户创建/更新事件.
  *
  * @param User $user
  * @return void
  */
 public function saved(User $user)
 {
  //
 }
 public function customing(User $user){
 }
  public function customed(User $user){
 }
}
Nach dem Login kopieren

3. Definition der statischen Methode

Wir können ein Ereignis auch über die entsprechende statische Methode im Modell definieren, die in der Boot-Methode von EventServiceProvider definiert ist:

Wenn
class User extends Authenticatable {
 use Notifiable;
 protected $observables = [
  'customing', 'awesoming'
 ];
 
 public function custom(){
  if ($this->fireModelEvent('customing') === false) {
   return false;
  }
  
  //TODO
   if ($this->fireModelEvent('customed') === false) {
   return false;
  }
 }
}
Nach dem Login kopieren

über eine statische Methode definiert wird, kann es direkt an einen Abschluss übergeben oder als Methode einer bestimmten Klasse definiert werden. Wenn das Ereignis ausgelöst wird, ist der übergebene Parameter die Modellinstanz.

2. Modellereignis-Implementierungsprinzip

Alle Codes für Laravel-Modellereignisse stehen unter dem Merkmal IlluminateDatabaseEloquentConcernsHasEvents. So registrieren Sie diese Ereignisse, wobei $dispatcher eine IlluminateContractsEventsDispatcher-Instanz des Ereignisverteilers ist, die in die Boot-Methode von IlluminateDatabaseDatabaseServiceProvider eingefügt wird.

class EventServiceProvider extends ServiceProvider{
 /**
  * Register any events for your application.
  *
  * @return void
  */
 public function boot()
 {
  parent::boot();
  User::saved(function(User$user) {
  });
  User::saved('UserSavedListener@saved');
 }
}
Nach dem Login kopieren

Hier werden Laravel-Ereignisse registriert, mit eloquent.saved:AppUser als Ereignisname und $callback als Prozessor. Bei dieser Methode zur Registrierung von Ereignissen werden nur diejenigen registriert, die als Beobachter und statische Methoden definiert sind. Wenn Sie es als $events-Attribut des Modells definieren, registriert Laravel es nicht und löst es synchron aus, wenn das Ereignis ausgelöst wird, das als nächstes analysiert wird.

Dann werden in HasEvents eine Reihe von Methoden wie folgt definiert: Dies sind die oben genannten Prinzipien zum Definieren von Ereignis-Listenern. Sie können sie auf einen Blick verstehen.

protected static function registerModelEvent($event, $callback){
  if (isset(static::$dispatcher)) {
   $name = static::class;
   static::$dispatcher->listen("eloquent.{$event}: {$name}", $callback);
  }
 }
Nach dem Login kopieren

Wie definiert man also Ereignis-Listener in Form von Beobachtern? Schauen Sie sich den Quellcode an:

public static function saving($callback){
 static::registerModelEvent('saving', $callback);
}
public static function saved($callback){
 static::registerModelEvent('saved', $callback);
}
Nach dem Login kopieren

Rufen Sie zuerst den Klassennamen des Beobachters ab und ermitteln Sie dann, ob eine Methode vorhanden ist, die dem Ereignisnamen entspricht. Rufen Sie hier auch registerModelEvent auf, um sich zu registrieren Enthält diejenige, die wir im Observables-Array definiert haben.

Nachdem die Ereignisse und Listener definiert sind, ist es an der Zeit, sie auszulösen. Wie bereits erwähnt, gibt es eine Methode fireModelEvent. Schauen wir uns den Quellcode an:

 protected function fireModelEvent($event, $halt = true)
 {
  if (! isset(static::$dispatcher)) {
   return true;
  }
  $method = $halt ? 'until' : 'fire';
  $result = $this->filterModelEventResults(
   $this->fireCustomModelEvent($event, $method)
  );
  if ($result === false) {
   return false;
  }
  return ! empty($result) ? $result : static::$dispatcher->{$method}(
   "eloquent.{$event}: ".static::class, $this
  );
 }
Nach dem Login kopieren

其中比较关键的一个方法是fireCustomModelEvent,它接受一个事件名以及触发方式。顺带一提,filterModelEventResults这个方法的作用就是把监听器的返回值为null的过滤掉。

看看fireCustomModelEvent的源码:

 protected function fireCustomModelEvent($event, $method)
 {
  if (! isset($this->events[$event])) {
   return;
  }
  $result = static::$dispatcher->$method(new $this->events[$event]($this));
  if (! is_null($result)) {
   return $result;
  }
 }
Nach dem Login kopieren

这个就是用来触发我们通过$events定义的事件了,假如我们这么定义:

class User extends Model{
 protected $events = [
  'saved' => UserSaved::class
 ]
}
Nach dem Login kopieren

那这里的触发就是:

 $result = static::$dispatcher->fire(new UserSaved($this));
Nach dem Login kopieren

顺带一提,Laravel中触发事件的方法有两个,一个是常用的fire,还有一个是util,这两个的差别就是fire会把监听器的返回值返回,而util永远返回null

然后接下来就是会去触发通过观察者和静态方法定义的监听器了,这一段代码:

  if ($result === false) {
   return false;
  }
  return ! empty($result) ? $result : static::$dispatcher->{$method}(
   "eloquent.{$event}: ".static::class, $this
  );
Nach dem Login kopieren

这里会先判断$events定义的监听器是否返回false以及返回值是否为空,如果为false则直接结束事件,如果返回不为false而且为空的话,会再去触发通过观察者和静态方法定义的监听器,并且把监听器的返回值返回。
完。

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

phpStudy2018安装与配置步骤详解

ThinkPHP实现微信支付(jsapi支付)步骤详解

Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung der Schritte zur Implementierung von Laravel-Modellereignissen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
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
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!