Laravel路由访问次数统计功能实现咨询
Laravel非认证路由访问次数统计方案
当然可以实现!Laravel的中间件机制完美适配这个需求——不管路由是否需要用户认证,都能轻松拦截请求并统计访问次数。下面我一步步给你拆解具体实现方式,以及存储方案的选择:
是否可实现?
完全没问题。Laravel的中间件是请求生命周期的核心环节,能在请求到达控制器前/后执行自定义逻辑,正好用来做路由访问统计,和路由是否需要认证没有绑定关系。
具体实现方式
核心思路是自定义中间件,通过它拦截目标路由的请求,然后更新访问次数统计。
1. 创建自定义中间件
先执行Artisan命令生成中间件:
php artisan make:middleware RouteVisitCounter
打开生成的app/Http/Middleware/RouteVisitCounter.php,在handle方法里编写统计逻辑。首先我们需要一个路由标识(可以用路由名称,没有名称的话用请求路径):
<?php namespace App\Http\Middleware; use Closure; use Illuminate\Http\Request; class RouteVisitCounter { public function handle(Request $request, Closure $next) { // 获取路由唯一标识:优先用路由名称,没有则用请求路径 $routeKey = $request->route()->getName() ?: $request->path(); // 排除不需要统计的路由(可选,比如健康检查接口) $excludedRoutes = ['health-check', 'api/monitor']; if (in_array($routeKey, $excludedRoutes)) { return $next($request); } // 这里添加统计逻辑,下面分不同存储方式讲解 $this->updateVisitCount($routeKey); return $next($request); } // 封装统计更新方法,方便切换存储方式 private function updateVisitCount(string $routeKey) { // 这里写具体的存储逻辑,下面会给出不同方案 } }
2. 注册中间件
有两种注册方式,根据你的需求选择:
- 全局注册:所有路由都统计,在
app/Http/Kernel.php的$middleware数组中添加中间件类:protected $middleware = [ // ... 其他中间件 \App\Http\Middleware\RouteVisitCounter::class, ]; - 分组注册:只统计特定路由(比如你的非认证路由组),先给中间件起别名(在
app/Http/Kernel.php的$routeMiddleware数组中添加):
然后在路由文件中使用:protected $routeMiddleware = [ // ... 其他别名 'route.counter' => \App\Http\Middleware\RouteVisitCounter::class, ];Route::middleware('route.counter')->group(function () { // 你的非认证路由示例 Route::get('/public/article/{id}', [ArticleController::class, 'show'])->name('public.article.show'); Route::get('/public/faq', [FaqController::class, 'index']); });
3. 选择存储方案(核心部分)
这里重点回答你的第三个问题:不需要必须存储到数据库,可以根据业务需求选不同存储方式:
方案一:数据库存储(持久化,适合长期统计)
适合需要留存历史数据、后续要做数据分析的场景。
- 首先创建迁移文件:
php artisan make:migration create_route_visits_table - 编写迁移字段:
public function up() { Schema::create('route_visits', function (Blueprint $table) { $table->id(); $table->string('route_key')->unique(); // 路由标识,唯一索引 $table->integer('visit_count')->default(0); // 访问次数 $table->timestamps(); }); } - 执行迁移:
php artisan migrate - 创建对应模型
app/Models/RouteVisit.php:<?php namespace App\Models; use Illuminate\Database\Eloquent\Model; class RouteVisit extends Model { protected $fillable = ['route_key', 'visit_count']; } - 在中间件的
updateVisitCount方法中写入逻辑:use App\Models\RouteVisit; private function updateVisitCount(string $routeKey) { // 用updateOrIncrement实现"存在则加1,不存在则创建" RouteVisit::updateOrIncrement( ['route_key' => $routeKey], ['visit_count' => \DB::raw('visit_count + 1')] ); }
方案二:缓存存储(高性能,适合临时/短期统计)
适合不需要持久化、追求高性能的场景(比如统计近7天的访问量),Laravel支持多种缓存驱动(文件、Redis等):
use Illuminate\Support\Facades\Cache; private function updateVisitCount(string $routeKey) { $cacheKey = "route_visits:{$routeKey}"; // 先确保缓存键存在,初始值为0 if (!Cache::has($cacheKey)) { Cache::put($cacheKey, 0, now()->addDays(7)); // 设置7天过期 } // 自增访问次数 Cache::increment($cacheKey); }
方案三:Redis存储(高并发场景)
如果你的项目已经用了Redis,直接用它做统计性能最好,用法和缓存几乎一致——只要把Laravel的缓存驱动配置为Redis即可,代码和方案二完全一样。
总结
- 非认证路由的访问次数统计在Laravel中完全可实现,核心是用自定义中间件拦截请求;
- 实现步骤:创建中间件→注册中间件→选择存储方案;
- 不是必须存储到数据库,可根据需求选择数据库(持久化)、缓存(临时统计)、Redis(高并发)等方案。
内容的提问来源于stack exchange,提问作者Guilherme Keunecke Bangemann
相关产品推荐
相关产品推荐

