thinkphp8软删除模型在查询时若未正确配置或缓存键中缺失`delete_time`字段,会导致已删除数据被错误地重新加载到缓存中,造成数据不一致。具体做法是确保查询条件显式包含`delete_time is null`,并在生成缓存键时将该字段纳入计算,从而避免脏读。

软删除查询为何会漏掉delete_time
ThinkPHP的软删除机制依赖于模型中的`$defaultSoftDelete`属性或手动设置的`deleteTime`字段。当执行查询时,框架会自动追加`where(delete_time, 'is', null)`条件。如果开发者手动构建了查询构造器且未调用`softDelete()`方法,或者在使用缓存时直接使用了原始SQL而未让ORM介入,这个自动追加的条件就会丢失。此时,数据库中存在`delete_time`不为空的记录会被当作有效数据返回,并可能被写入缓存。

修复 Core bailout 状态损坏安全问题,以及 BZ2、DOM、PDO、Opcache/JIT 内存与执行错误,改进 Unicode 字素处理、URL 解析、TLS 流状态、信号分发及会话错误处理。
use think\model\Model;
class Article extends Model
{
protected $name = 'article';
protected $autoWriteTimestamp = true;
protected $deleteTime = 'delete_time';
public function getArticleById($id)
{
// 错误示范:直接使用Db或忽略软删除
$data = Db::name('article')->where('id', $id)->find();
return $data;
}
public function getArticleBySoftDelete($id)
{
// 正确示范:使用模型查询,自动追加delete_time条件
return $this->where('id', $id)->find();
}
}预期结果:`getArticleById`可能返回已删除(`delete_time`有值)的数据;`getArticleBySoftDelete`仅返回未删除(`delete_time`为null)的数据。
立即学习“PHP免费学习笔记(深入)”;
缓存键如何因缺少delete_time导致冲突
在分布式缓存或本地静态缓存中,缓存键通常由主键和关键状态组成。如果缓存键只包含`id`,而忽略了`delete_time`,那么当一条数据被软删除后,其`id`不变,但逻辑状态已从“存在”变为“不存在”。此时,如果有新的数据插入复用了该`id`(虽然罕见,但在某些ID复用策略下可能发生),或者仅仅是因为缓存未失效,旧的有效数据缓存项依然存在于缓存中。更常见的情况是,查询代码中手动拼接了缓存Key,如`cache_key =


















