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

如何将所有404请求记录到数据库?Laravel实现疑问

嘿,这个需求其实Laravel已经有很方便的解决方案啦!我来一步步给你捋清楚怎么实现,顺便优化下你现有的代码~

方案一:用路由Fallback(最简单直接)

Laravel提供了fallback路由,专门用来处理所有未匹配到其他路由的请求——也就是我们常说的404场景,完全不用折腾中间件或者服务提供者,几步就能搞定:

1. 优化你的控制器方法

你原来的代码可以简化很多,用Laravel的updateOrCreate方法就能一键完成“存在则计数+1,不存在则新增”的逻辑,而且原来的empty(MissingPage::where('slug', $slug)->get())写法不太靠谱(因为get()返回的是集合,即使为空也不是严格的empty),改成下面这样更高效:

use Illuminate\Http\Request;
use App\Models\MissingPage;
use Illuminate\Support\Facades\DB;

public function test(Request $request)
{
    // 获取当前请求的路径,比如访问example.com/demo的话,这里拿到的就是"demo"
    $slug = $request->path();
    
    // 如果你只想记录路径的第一部分(比如example.com/demo/subpage只记录"demo"),可以改成:
    // $slug = explode('/', $request->path())[0];
    
    // 一键完成新增/更新操作
    MissingPage::updateOrCreate(
        ['slug' => $slug], // 匹配条件:slug等于当前请求的路径
        ['count' => DB::raw('count + 1')] // 如果存在,count字段加1;如果不存在,默认count为1(需要在模型里设置默认值,或者改成['count' => 1])
    );
    
    // 最后一定要返回404响应,让Laravel显示你自定义的404页面
    abort(404);
}

2. 在web.php里配置Fallback路由

只需要在路由文件的末尾加上这一行(一定要放在所有其他路由的后面,因为路由是按顺序匹配的):

use App\Http\Controllers\MissingPageController;

Route::fallback([MissingPageController::class, 'test']);

这样一来,所有没被其他路由匹配到的请求,都会自动走到这个test方法里完成记录,然后返回404页面,完美!

方案二:用全局中间件(适合全场景捕获404)

如果你的应用既有web端又有API端,或者需要更全局的404捕获,那用中间件会更灵活:

1. 创建中间件

先执行Artisan命令生成中间件:

php artisan make:middleware RecordMissingPage

2. 编写中间件逻辑

打开app/Http/Middleware/RecordMissingPage.php,修改handle方法:

use Illuminate\Http\Request;
use App\Models\MissingPage;
use Illuminate\Support\Facades\DB;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

public function handle(Request $request, Closure $next)
{
    try {
        $response = $next($request);
        
        // 检查响应状态码是否是404
        if ($response->getStatusCode() === 404) {
            $this->recordMissingPage($request);
        }
        
        return $response;
    } catch (NotFoundHttpException $e) {
        // 捕获代码里主动抛出的404异常(比如abort(404))
        $this->recordMissingPage($request);
        
        // 继续抛出异常,让Laravel处理404页面
        throw $e;
    }
}

// 抽离成单独的方法,更清晰
private function recordMissingPage(Request $request)
{
    $slug = $request->path();
    
    // 可以在这里排除静态资源(比如css、js、图片),避免无效记录
    $excludedExtensions = ['css', 'js', 'png', 'jpg', 'svg', 'ico'];
    $extension = pathinfo($slug, PATHINFO_EXTENSION);
    if (in_array($extension, $excludedExtensions)) {
        return;
    }
    
    MissingPage::updateOrCreate(
        ['slug' => $slug],
        ['count' => DB::raw('count + 1')]
    );
}

3. 注册中间件

打开app/Http/Kernel.php,把这个中间件加到web中间件组里(如果需要API也生效,就加到api组):

protected $middlewareGroups = [
    'web' => [
        // ... 其他已有的中间件
        \App\Http\Middleware\RecordMissingPage::class,
    ],
];
额外提醒
  • 记得给missing_pages表的slug字段加唯一索引,这样updateOrCreate能准确匹配,避免重复数据;
  • 如果你的count字段默认值不是1,记得在模型里设置$attributes = ['count' => 1];,或者在updateOrCreate的第二个参数里写['count' => 1];
  • 如果不想记录某些特定路径,可以在方法里加判断过滤掉。

内容的提问来源于stack exchange,提问作者Ali Özen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 05:11:39