最近刚好用上模型事件,但手册上对事件的触发条件却没有详细的进行说明。那么,就只能自己进行测试了。
首先,从手册上,我们可以知道模型支持以下事件:
事件 | 描述 | 事件方法名 |
---|---|---|
after_read | 查询后 | onAfterRead |
before_insert | 新增前 | onBeforeInsert |
after_insert | 新增后 | onAfterInsert |
before_update | 更新前 | onBeforeUpdate |
after_update | 更新后 | onAfterUpdate |
before_write | 写入前 | onBeforeWrite |
after_write | 写入后 | onAfterWrite |
before_delete | 删除前 | onBeforeDelete |
after_delete | 删除后 | onAfterDelete |
before_restore | 恢复前 | onBeforeRestore |
after_restore | 恢复后 | onAfterRestore |
为了了解每个事件的触发条件,我们先建立以下模型
app/model/Users.php
<?php
namespace app\model;
use think\Model;
use think\model\concern\SoftDelete;
class Users extends Model
{
// 软删除
use SoftDelete;
public static function onAfterRead($user) {
dump('查询后');
}
public static function onBeforeInsert($user) {
dump('新增前');
}
public static function onAfterInsert($user) {
dump('新增后');
}
public static function onBeforeUpdate($user) {
dump('更新前');
}
public static function onAfterUpdate($user) {
dump('更新后');
}
public static function onBeforeWrite($user) {
dump('写入前');
}
public static function onAfterWrite($user) {
dump('写入后');
}
public static function onBeforeDelete($user) {
dump('删除前');
}
public static function onAfterDelete($user) {
dump('删除后');
}
public static function onBeforeRestore($user) {
dump('恢复前');
}
public static function onAfterRestore($user) {
dump('恢复后');
}
}
CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',
`name` varchar(32) NOT NULL COMMENT '姓名',
`area` varchar(32) NOT NULL COMMENT '区域',
`address` varchar(64) NOT NULL COMMENT '地址',
`balance` decimal(9,2) NOT NULL COMMENT '余额',
`password` varchar(255) NOT NULL COMMENT '密码',
`status` int(11) NOT NULL COMMENT '状态',
`last` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '最后活跃时间',
`phone` varchar(11) NOT NULL COMMENT '手机号',
`delete_time` int(10) unsigned DEFAULT NULL COMMENT '删除时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='用户表'
然后通过以下代码去操作数据库
use \app\model\Users;
$data = [
'name' => 'test',
'phone' => '13888888888',
'area' => '0',
'address' => '广东省韶关市',
'balance' => '0',
'password' => '0',
'status' => '0',
'last' => '2019-01-01 00:00:00',
];
dump('Users::create($data)');
$users = Users::create($data);
dump('Users::insert($data)');
Users::insert($data);
dump('Users::where("id", $users["id"])->update(["area" => 1])');
Users::where("id", $users["id"])->update(["area" => 1]);
dump('Users::update(["area" => 1], ["id" => $users["id"]])');
Users::update(["area" => 1], ["id" => $users["id"]]);
dump('$users->save(["area" => 2])');
$users->save(["area" => 2]);
dump('Users::where("id", $users["id"])->delete()');
Users::where("id", $users["id"])->delete();
dump('Users::where("id", ">", 0)->find()');
$users = Users::where("id", ">", 0)->find();
dump('Users::destroy($users["id"])');
Users::destroy($users["id"]);
dump('$users->restore()');
$users->restore();
dump('$users->delete()');
$users->delete();
执行之后,返回以下结果
^ "Users::create($data)"
^ "写入前"
^ "新增前"
^ "新增后"
^ "写入后"
^ "Users::insert($data)"
^ "Users::where("id", $users["id"])->update(["area" => 1])"
^ "Users::update(["area" => 1], ["id" => $users["id"]])"
^ "写入前"
^ "更新前"
^ "更新后"
^ "写入后"
^ "$users->save(["area" => 2])"
^ "写入前"
^ "更新前"
^ "更新后"
^ "写入后"
^ "Users::where("id", $users["id"])->delete()"
^ "Users::where("id", ">", 0)->find()"
^ "查询后"
^ "Users::destroy($users["id"])"
^ "查询后"
^ "删除前"
^ "删除后"
^ "$users->restore()"
^ "恢复前"
^ "恢复后"
^ "$users->delete()"
^ "删除前"
^ "删除后"
模型创建数据方法,会触发写入前
、新增前
、新增后
、写入后
。使用模型的save()
和saveAll()
来新增方法也会触发这几个事件。
insert()
是Db类的方法,不是模型方法,不会触发模型事件。
update()
是Db类的方法,不是模型方法,不会触发模型事件。
如果是模型静态调用
update()
,则执行的是模型的update
方法,而模型的update
方法会调用save()
方法,所以跟模型的save()
方法一样,会触发写入前
、更新前
、更新后
、写入后
事件 感谢 @dejavu 的提醒
使用模型的save()
方法来更新数据,会触发写入前
、更新前
、更新后
、写入后
事件。
如果是使用模型方法查询出来数据,然后再删除数据,则会触发删除前
、删除后
事件。
如果是直接使用条件删除,则不会触发模型事件。因为直接使用条件删除,这时候的delete()
方法不是模型方法。
该查询方法会触发查询后
事件
该删除数据方法会触发查询后
、删除前
、删除后
。所以,该方法是先查询出数据,然后再删除该数据。
该软删除恢复方法会触发恢复前
、恢复后
方法