Ereignis


Wie definiere ich Ereignisse?

Alle Operationen des Ereignissystems werden statisch über die thinkfacadeEvent-Klasse aufgerufen

Das Ereignissystem verwendet das Beobachtermuster (siehe PHP-Entwurfsmuster), um eine bessere Möglichkeit zur Entkopplung von Anwendungen zu bieten.

Wenn Sie beispielsweise auf Ereignisse warten müssen, fügen wir unten den folgenden Code zum Auslösen von Ereignissen hinzu, nachdem der Benutzer den Anmeldevorgang abgeschlossen hat:

// 触发UserLogin事件 用于执行用户登录后的一系列操作
Event::trigger('UserLogin');


Hier UserLogin stellt eine Ereignisidentifikation dar. Wenn Sie eine separate Ereignisklasse definieren, können Sie den Namen der Ereignisklasse verwenden (Sie können sogar eine Ereignisklasseninstanz übergeben).

// 直接使用事件类触发
event('app\event\UserLogin');

Die Ereignisklasse kann schnell über die Befehlszeile generiert werden.

php think make:event UserLogin

Standardmäßig wird eine appeventUserLogin-Ereignisklasse generiert, oder Sie können den vollständigen Klassennamen angeben, um sie zu generieren.

Wir können Methoden zu Ereignisklassen hinzufügen

namespace app\event;

use app\model\User;

class UserLogin
{
    public $user;

    public function __construct(User $user)
    {
        $this->user = $user;
    }
}

Allgemeine Ereignisklassen müssen keine anderen Klassen erben.

Sie können eine Ereigniskennung an die Ereignisklasse binden. Es wird im Allgemeinen empfohlen, sie stapelweise direkt in der Ereignisdefinitionsdatei event.php der Anwendung zu binden.

return [
    'bind'    =>    [
        'UserLogin' => 'app\event\UserLogin',
        // 更多事件绑定
    ],
];

Wenn Sie eine dynamische Bindung benötigen, können Sie

Event::bind(['UserLogin' => 'app\event\UserLogin']);

Das Ereignissystem von ThinkPHP basiert nicht auf Ereignisklassen. Wenn keine zusätzlichen Anforderungen bestehen, kann es nur durch Ereignisidentifizierung verwendet werden, wodurch es eliminiert wird die Notwendigkeit, Klassenprobleme zu definieren.

Wenn Sie keine Ereignisklasse definieren, ist keine Bindung erforderlich. In den meisten Szenarien besteht möglicherweise tatsächlich keine Notwendigkeit, eine Ereignisklasse zu definieren.

Sie können einen Ereignisparameter in der Ereignismethode übergeben

// user是当前登录用户对象实例
event('UserLogin', $user);

Auf Ereignisse warten

Sie können einen Ereignis-Listener manuell registrieren

Event::listen('UserLogin', function($user) {
    // 
});

Oder nutzen Sie den Hörkurs dazu Überwachung ausführen

Event::listen('UserLogin', 'app\listener\UserLogin');

Sie können schnell eine Ereignis-Überwachungsklasse über die Befehlszeile generieren

php think make:listener UserLogin

Standardmäßig wird eine Ereignis-Überwachungsklasse applistenerUserLogin generiert, oder Sie können den vollständigen zu generierenden Klassennamen angeben .

Die Event-Listening-Klasse muss nur eine Handle-Methode definieren und unterstützt die Abhängigkeitsinjektion.

<?php
namespace app\listener;

class UserLogin
{
    public function handle($user)
    {
        // 事件监听处理
    }   
}

Wenn in der Handle-Methode false zurückgegeben wird, bedeutet dies, dass die Überwachung beendet ist und die Überwachung nach dem Ereignis nicht mehr ausgeführt wird.

Generell wird empfohlen, die Überwachung des entsprechenden Ereignisses direkt in der Ereignisdefinitionsdatei zu definieren.

return [
    'bind'    =>    [
        'UserLogin' => 'app\event\UserLogin',
        // 更多事件绑定
    ],
    'listen'  =>    [
        'UserLogin'    =>    ['app\listener\UserLogin'],
        // 更多事件监听
    ],
];

Ereignisabonnement

Sie können über den Ereignisabonnementmechanismus mehrere Ereignisse in einem Listener abhören und beispielsweise über den Befehl eine Ereignisabonnentenklasse generieren Zeile ,

php think make:subscribe User

generiert standardmäßig die appsubscribeUser-Klasse, oder Sie können den vollständigen zu generierenden Klassennamen angeben.

Dann können Sie beispielsweise Überwachungsmethoden für verschiedene Ereignisse in der Ereignisabonnementklasse hinzufügen.

<?php
namespace app\subscribe;

class User
{
    public function onUserLogin($user)
    {
        // UserLogin事件响应处理
    }

    public function onUserLogout($user)
    {
        // UserLogout事件响应处理
    }
}

Die Namenskonvention für Methoden zum Abhören von Ereignissen lautet „on event Identifier“ (Kamelfallbenennung) und registriert dann Ereignisabonnenten in der Ereignisdefinitionsdatei.

return [
    'bind'    =>    [
        'UserLogin' => 'app\event\UserLogin',
        // 更多事件绑定
    ],
    'listen'  =>    [
        'UserLogin'    =>    ['app\listener\UserLogin'],
        // 更多事件监听
    ],
    'subscribe'    =>    [
       'app\subscribe\User',
        // 更多事件订阅
    ],
];

Wenn Sie Ereignispräfix-IDs einheitlich hinzufügen möchten, können Sie das Attribut „eventPrefix“ definieren.

<?php
namespace app\subscribe;

class User
{
    protected $eventPrefix = 'User';

    public function onLogin($user)
    {
        // UserLogin事件响应处理
    }

    public function onLogout($user)
    {
        // UserLogout事件响应处理
    }
}

Wenn Sie die Abonnementmethode (oder Methodenspezifikation) anpassen möchten, können Sie die Implementierung der Abonnementmethode definieren.

<?php
namespace app\subscribe;

use think\Event;

class User
{
    public function onUserLogin($user)
    {
        // UserLogin事件响应处理
    }

    public function onUserLogout($user)
    {
        // UserLogout事件响应处理
    }

    public function subscribe(Event $event)
    {
        $event->listen('UserLogin', [$this,'onUserLogin']);
        $event->listen('UserLogout',[$this,'onUserLogout']);
    }
}

Wenn Sie sich dynamisch registrieren müssen, können Sie

Event::subscribe('app\index\subscribe\User');

Eingebaute Ereignisse

Zu den integrierten Systemereignissen gehören:


事件描述参数
AppInit应用初始化标签位
HttpRun应用开始标签位
HttpEnd应用结束标签位当前响应对象实例
LogWrite日志write方法标签位当前写入的日志信息
LogLevel日志写入标签位包含日志类型和日志信息的数组
RouteLoaded路由加载完成

Die AppInit-Ereignisdefinition muss in der globalen Ereignisdefinitionsdatei definiert werden, und andere Ereignisse können in der Ereignisdefinitionsdatei der Anwendung definiert werden.

Einige der ursprünglichen Verhaltens-Tags in 5.1 wurden aufgegeben und alle gelöschten Tags können durch bessere Middleware ersetzt werden. Unter Middleware versteht man spezielle Ereignisse im Zusammenhang mit der Verarbeitung von Anfragen und der Reaktion auf Ausgaben. Tatsächlich verfügt die Handler-Methode der Middleware nur über spezielle Parameter und Rückgabewerte.

Rückrufe für Datenbankoperationen werden auch als Abfrageereignisse bezeichnet. Sie sind Rückrufmethoden, die für CURD-Operationen der Datenbank entwickelt wurden. Sie umfassen hauptsächlich:


事件描述
before_selectselect查询前回调
before_findfind查询前回调
after_insertinsert操作成功后回调
after_updateupdate操作成功后回调
after_deletedelete操作成功后回调

Der Parameter des Abfrageereignisses ist die aktuelle Abfrageobjektinstanz.

Zu den Modellveranstaltungen gehören:


钩子对应操作
after_read查询后
before_insert新增前
after_insert新增后
before_update更新前
after_update更新后
before_write写入前
after_write写入后
before_delete删除前
after_delete删除后