ThinkPHP6之模型事件的触发条件
最近刚好用上模型事件,但手册上对事件的触发条件却没有详细的进行说明。那么,就只能自己进行测试了。
模型事件
首先,从手册上,我们可以知道模型支持以下事件:
事件 | 描述 | 事件方法名 |
---|---|---|
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()"
^ "删除前"
^ "删除后"
总结
方法 | 查询后 | 新增前 | 新增后 | 更新前 | 更新后 | 写入前 | 写入后 | 删除前 | 删除后 | 恢复前 | 恢复后 |
---|---|---|---|---|---|---|---|---|---|---|---|
create() | √ | √ | √ | √ | |||||||
insert() | |||||||||||
update() | √ | √ | √ | √ | |||||||
save() | √ | √ | √ | √ | |||||||
delete() | √ | √ | |||||||||
find() | √ | ||||||||||
destroy() | √ | √ | √ | ||||||||
restore() | √ | √ |
create()
模型创建数据方法,会触发写入前
、新增前
、新增后
、写入后
。使用模型的save()
和saveAll()
来新增方法也会触发这几个事件。
insert()
insert()
是Db类的方法,不是模型方法,不会触发模型事件。
update()
update()
是Db类的方法,不是模型方法,不会触发模型事件。
如果是模型静态调用update()
,则执行的是模型的update
方法,而模型的update
方法会调用save()
方法,所以跟模型的save()
方法一样,会触发写入前
、更新前
、更新后
、写入后
事件
感谢 @dejavu 的提醒
save()
使用模型的save()
方法来更新数据,会触发写入前
、更新前
、更新后
、写入后
事件。
delete()
如果是使用模型方法查询出来数据,然后再删除数据,则会触发删除前
、删除后
事件。
如果是直接使用条件删除,则不会触发模型事件。因为直接使用条件删除,这时候的delete()
方法不是模型方法。
find()
该查询方法会触发查询后
事件
destroy()
该删除数据方法会触发查询后
、删除前
、删除后
。所以,该方法是先查询出数据,然后再删除该数据。
restore()
该软删除恢复方法会触发恢复前
、恢复后
方法
好好学习,天天向上!
感谢
destroy 已经不能触发模型事件了 6.0.9版本
经过测试,Model::destroy()方法可以正常触发模型事件,跟以前没什么变化。
update()方法,如果是通过where()调用,使用的是Db类的方法,不触发模型事件;
如果是通过模型静态方法调用,最终调用的还是模型的save()方法,触发模型事件。
感谢提醒,已更新
好强的思维方式。谢谢分享!!
厉害厉害
共同学习,共同进步