thinkphp软删除未生效因模型未正确定义$deletetime属性或错误使用where条件;查已删记录须用wherenotnull(),启用需use softdelete并设$deletetime='delete_time'。

软删除字段没生效,where 条件查不到已“删除”的记录
ThinkPHP 的软删除默认只对 select、find 类查询自动过滤掉 delete_time != null 的数据。如果你手动加了 where('delete_time', 'null') 或类似条件,反而会和软删除机制冲突——因为真实值是 NULL(数据库 NULL),不是字符串 'null',更不是 0 或空字符串。
常见错误写法:where('delete_time', 'null')、where('delete_time', '')、where('delete_time', 0),这些全都不匹配数据库里的 NULL 值。
- 查“已软删除”的记录,必须用
whereNull('delete_time')(查未删)或whereNotNull('delete_time')(查已删) - 若模型启用了软删除(
use SoftDelete;),默认所有select都带where delete_time is null,想绕过它得显式调用withTrashed() -
withoutTrashed()是默认行为,一般不用显式写;但onlyTrashed()等价于whereNotNull('delete_time')
withTrashed() 不起作用?检查模型是否真正启用软删除
光在模型里 use SoftDelete; 不够,还必须定义 $deleteTime 属性,否则框架不认为该模型支持软删除,withTrashed() 就只是个空方法,不会修改查询条件。
典型缺失配置:
class User extends Model
{
use SoftDelete;
// ❌ 缺少这行,软删除机制不激活
protected $deleteTime = 'delete_time';
}
-
$deleteTime必须是字符串,如'delete_time';设为false或留空会禁用软删除 - 字段类型建议用
datetime或timestamp,避免用int存时间戳再手动赋值,容易因时区/格式导致NULL判断失败 - 如果表中该字段允许
NULL但默认值设成了0或'0000-00-00 00:00:00',那whereNotNull也查不到——得先清理脏数据
调试实际执行的 SQL:看 delete_time 条件到底有没有加进去
别猜,直接看框架生成的 SQL。ThinkPHP 6+ 可用 getLastSql(),TP5 用 getRealSql(),配合 fetchSql(true) 强制不执行只返回 SQL。
例如:
$list = User::withTrashed()->where('status', 1)->fetchSql(true)->select();
echo $list; // 输出类似:SELECT * FROM `user` WHERE `status` = 1 AND `delete_time` IS NOT NULL
- 如果输出里没有
delete_time相关条件,说明软删除未启用,或调用了错误的方法(比如在withTrashed()前用了where且模型未初始化软删除) - 注意:
fetchSql(true)返回的是字符串,不是结果集,别把它当数据用 - TP6 中
Db::name('user')->withTrashed()->select()也有效,但必须确保是模型查询入口,原生 Db 查询不识别软删除逻辑
关联查询中软删除失效:子模型没启用 or 关联没透传
主模型调了 withTrashed(),但关联的 has 或 belongsToMany 查出来的子记录仍是“被过滤后”的,因为关联查询默认不继承主模型的软删除策略。
- 一对一/一对多关联:在关联方法里显式加
->withTrashed(),例如return $this->hasMany('Order')->withTrashed(); - 多对多中间表如果也用了软删除,需在中间模型里单独启用,并在关联定义中指定中间模型类
- 使用
with(['orders' => function ($q) { $q->withTrashed(); }])才能控制关联查询是否包含已删除项 - 切记:软删除是模型级行为,不是全局 DB 行为,每个参与查询的模型都得自己配好
$deleteTime和SoftDelete
软删除最易忽略的点在于“多层嵌套时各模型自治”,一个没配,整条链就断在那儿了。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











