TP6已移除before_select事件,因其重构了查询机制,改用Query层的BeforeExecute事件和模型scope替代;TP5.1/5.2中该事件仅支持日志等旁路操作,无法修改查询条件。
ThinkPHP 的事件在 6.x 版本中已被移除,5.1/5.2 仍支持但行为受限——它不接收查询条件参数,无法动态修改或,仅适合做日志记录或简单拦截。
为什么
在 TP6 中用不了
TP6 彻底重构了查询构建器与模型生命周期,取消了所有以
/
命名的模型事件。取而代之的是更统一、可组合的「查询作用域(scope)」和「事件监听器(Event Listener)」机制。
在 TP5.1/5.2 中触发时机早于 SQL 编译,但传入的参数只有
实例,没有
对象,无法干预实际查询逻辑
TP6 中模型不再直接暴露查询过程,
等方法底层调用的是
类,事件钩子已下沉到
层,对应的是
和
全局事件
试图在 TP6 模型中定义
方法不会报错,但完全不会被调用
TP5.1/5.2 中
的真实能力边界
它只能用于「只读旁路操作」,比如统计调用次数、写日志、抛异常中断,但不能改查询条件。
以下写法看似有效,实则无效:
—— 因为
参数根本不存在,
只接收
正确用法示例(仅日志):
若需统一加条件,请改用
:
TP6 替代方案:用
事件拦截原生查询
如果真需要在 SQL 执行前统一处理(如多租户字段注入、敏感字段过滤),必须监听数据库查询级别的事件,而非模型事件。
PHP 8.5.5
PHP 8.5.5 是 PHP 8.5 分支的维护更新版本。该版本延续了“小步快跑”的迭代逻辑,通过深度错误修复、底层性能微调以及安全加固,旨在为开发者提供一个更健壮、更高效的运行环境。该版本严格遵守语义化版本规范,不包含破坏性变更。
下载
立即学习
“
PHP免费学习笔记(深入)
”;
在
中注册:
接收
对象,可调用
查看当前条件,用
修改(注意:部分选项不可直接覆盖,需谨慎)
该事件影响所有查询(包括原生
),不是模型专属,务必加判断:
性能敏感场景慎用——每次查询都触发,且修改
可能破坏缓存一致性
真正要统一控制查询逻辑,别依赖已废弃的模型事件;TP5 就老实用
,TP6 就走
事件 + 表名判断。最常被忽略的一点:TP6 的模型
方法本身是静态代理,背后根本没有「模型级 select 钩子」这回事。
before_selectwherefieldbefore_selectbefore_*after_*before_select$model$queryselect()Querythink\db\QueryBeforeExecuteAfterExecutebefore_selectbefore_select$query->where('status', 1)$querybefore_select$modelprotected static function beforeSelect($model)
{
\think\Log::info('Model ' . get_class($model) . ' select triggered');
}scopepublic function scopeActive($query)
{
return $query->where('status', 1);
}
// 调用:UserModel::active()->select();BeforeExecuteapp/event.phpreturn [
'think\db\Query' => [
'BeforeExecute' => [\app\listener\QueryBeforeExecute::class, 'handle'],
],
];QueryBeforeExecute::handle()$query$query->getOptions()$query->options(['where' => [...]])Db::table()if ($query->getTable() === 'user') { ... }optionsscopeQueryselect()