You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel使用Cache缓存查询时firstOrFail未返回404如何解决

问题原因

该问题确实和Cache::remember的执行逻辑直接相关,同时存在一个容易忽略的笔误:

  • 缓存写入逻辑漏洞:当传入不存在的slug时,如果某次请求没有触发firstOrFail()的异常(比如异常被全局捕获后返回了null),Cache::remember会把这个null值作为正常结果写入缓存,后续相同slug的请求会直接读取缓存中的null,根本不会执行闭包内的数据库查询和firstOrFail()逻辑,自然不会返回404。
  • 变量名传递错误:控制器中向视图传递的变量名是country,你在Blade中使用的是$post,变量名不匹配本身也会抛出变量不存在的错误。
修复步骤
  • 第一步:对齐视图变量名
    修正控制器的传参键名,和视图内调用的变量名保持一致:
public function single($slug)
{
    return view('post.single', [
        'post' => $this->getPostBySlugCached($slug),
    ]);
}
  • 第二步:调整缓存查询逻辑,禁止缓存空结果
    修改缓存方法,数据库查询时先取结果,查不到就直接抛出404,不把null写入缓存:
private function getPostBySlugCached(string $slug)
{
    return Cache::tags(['post'])->remember('post:slug:'.$slug, CacheRemember::FOUR_WEEKS, function () use ($slug) {
        $post = Post::where('slug', $slug)->first();
        // 不存在直接中断返回404,不会走到缓存写入流程
        if (!$post) {
            abort(404);
        }
        return $post;
    });
}

注意:如果之前错误逻辑已经把空值写入缓存,先执行Cache::tags(['post'])->flush();清空该标签下的所有缓存,再验证效果。

  • 可选加固:统一配置模型缺失异常的响应逻辑
    如果想继续使用firstOrFail()写法,可以在全局异常处理中明确配置ModelNotFoundException的返回规则,避免异常被其他逻辑拦截返回null:
    打开app/Exceptions/Handler.php,在register方法中添加如下配置:
use Illuminate\Database\Eloquent\ModelNotFoundException;

$this->renderable(function (ModelNotFoundException $e, $request) {
    abort(404);
});

内容的提问来源于stack exchange,提问作者eskimo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 16:09:20