袁来如此的工作笔记
袁来如此的工作笔记
竹杖芒鞋轻胜马,谁怕? 一蓑烟雨任平生。

ThinkPHP6之模型事件的触发条件

浏览量:95

模型事件

首先,从手册上,我们可以知道模型支持以下事件:

事件 描述 事件方法名
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()

该软删除恢复方法会触发恢复前恢复后方法


打赏