💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
Lying的部分服务组件、控制器、AR继承自`lying\service\Service`,所以并不能定义构造函数(因为在`lying\service\Service`构造函数被定义为`final`),但是你可以重写`init()`来实现。 只要你的类继承自`lying\service\Service`,那么你就可以为这个类绑定一些事件,我们先来说一说Lying的一些事件: [TOC] ### 控制器事件 控制器基类预定义了两个事件: ~~~php /** * @var string 方法执行前事件ID */ const EVENT_BEFORE_ACTION = 'beforeAction'; /** * @var string 方法执行后事件ID */ const EVENT_AFTER_ACTION = 'afterAction'; ~~~ 控制器默认绑定了两个事件触发的方法: ~~~php //$instance是控制器的实例 $instance->on(self::EVENT_BEFORE_ACTION, [$instance, 'beforeAction']); $instance->on(self::EVENT_AFTER_ACTION, [$instance, 'afterAction']); ~~~ 这些事件会在控制器方法执行前和执行后分别进行调用(仅仅在调度器调度控制器的时候有效,手动实例化控制器不会触发。 默认触发执行的是当前控制器的`beforeAction()`方法和`afterAction()`方法。当然,如果你想绑定其他事件,你可以在控制器初始化方法里面定义: ~~~php public function init() { $this->on(self::EVENT_BEFORE_ACTION, $callback); $this->on(self::EVENT_AFTER_ACTION, $callback); } ~~~ > * 控制器事件所绑定的回调函数可接受一个参数,为`lying\event\ActionEvent`实例:`function (\lying\event\ActionEvent $event)`。 > * 事实上所有的时间回调函数都可接受一个参数,为`lying\service\Event`实例,`function (\lying\service\Event $event)`,`lying\event\ActionEvent`也是继承自`lying\service\Event`。 你可以在控制器回调事件获取以下参数: ~~~php public function beforeAction(\lying\event\ActionEvent $event) { parent::beforeAction($event); echo $event->action; //执行的方法名称 } public function afterAction(\lying\event\ActionEvent $event) { parent::afterAction($event); echo $event->action; //执行的方法名称 echo $event->response; //执行方法返回的结果 } ~~~ ### 数据库模型事件 如果你的模型继承了`lying\db\ActiveRecord`,那么你的数据库模型已经预定义了几个事件了: ~~~php /** * @var string 插入前触发的事件ID */ const EVENT_BEFORE_INSERT = 'beforeInsert'; /** * @var string 插入后触发的事件ID */ const EVENT_AFTER_INSERT = 'afterInsert'; /** * @var string 更新前触发的事件ID */ const EVENT_BEFORE_UPDATE = 'beforeUpdate'; /** * @var string 更新后触发的事件ID */ const EVENT_AFTER_UPDATE = 'afterUpdate'; /** * @var string 删除前触发的事件ID */ const EVENT_BEFORE_DELETE = 'beforeDelete'; /** * @var string 删除后触发的事件ID */ const EVENT_AFTER_DELETE = 'afterDelete'; /** * @var string 插入或更新前触发的事件ID */ const EVENT_BEFORE_SAVE = 'beforeSave'; /** * @var string 插入或更新后触发的事件ID */ const EVENT_AFTER_SAVE = 'afterSave'; ~~~ 这些事件并没有像控制器那样默认绑定了触发函数,你可以这样为一个模型实例绑定触发函数: ~~~php $user = new User(); $user->on(User::EVENT_BEFORE_INSERT, function(\lying\event\ActiveRecordEvent $event) { echo $event->rows; //执行后受影响的函数,执行失败为false //你想执行的操作 }); ~~~ 你也可以在模型实例化的时候绑定好事件: ~~~php <?php namespace module\index\model; use lying\db\ActiveRecord; class UserModel extends ActiveRecord { public function init() { $this->on(self::EVENT_BEFORE_INSERT, function (\lying\event\ActiveRecordEvent $event) {}); $this->on(self::EVENT_AFTER_INSERT, [$this, 'afterInsert'], '带入的参数,可以在回调事件获取'); } public function afterInsert(\lying\event\ActiveRecordEvent $event) { echo $event->data; //获取到'带入的参数,可以在回调事件获取' } } ~~~ * `on`的第二个参数为`callable`类型。这些绑定的事件会在实例执行特定的操作的时候触发,事件可以绑定多个,按绑定顺序触发。 * `on`的第三个参数为`mixed`类型。这个参数可以在回调事件的参数中获取。 * `on`的第四个参数为`bool`类型。是否插入在事件队列的末尾,默认true,若果为false则插入到事件处理队列的首位 > * EVENT_BEFORE_INSERT、EVENT_BEFORE_UPDATE、EVENT_BEFORE_DELETE、EVENT_BEFORE_SAVE事件所绑定的回调函数接收到的参数:`$event->rows`为`null`。 > * EVENT_AFTER_INSERT、EVENT_AFTER_UPDATE、EVENT_AFTER_DELETE、EVENT_AFTER_SAVE事件所绑定的回调函数接受一个参数,为执行结果:`$event->rows`为`int`或者`false`。 ### 自定义事件 你可以在已经有的数据库模型类、控制器类定义其他自定义事件: 1. 定义一个事件ID,但是不能和预定义的事件ID一样:`const EVENT_EVENTNAME = 'enentId';`。 2. 在要触发事件的地方写上事件触发函数:`$this->trigger($id, $event)`。这里的`$id`就是你定义的事件ID,`$event`就是传到绑定的方法的参数,为一个`lying\service\Event实例`。 3. 在你需要的地方写上事件绑定函数`$this->on($id, $callback)`。这里的`$id`就是你定义的事件ID,`$callback`就是你绑定的回调函数。 ### 卸载事件 ~~~php $service->off($id, $callback); ~~~ `$service`为`lying\service\Service`的子类实例,`$id`为事件ID,`$callback`就是你要卸载的回调函数。如果`$callback`放空则表示清空整个事件ID所有的回调函数。 ### 事件执行顺序 > * 事件回调函数的执行顺序按照绑定的先后顺序执行。 > * 如果有一个事件的函数返回了false或者设置`$event->stop = false;` 则后面的事件就都不再执行