标签 Laravel 下的文章

Livewire Filemanager(一个在 Laravel PHP 框架中广泛使用的文件管理工具)中被发现了一个严重的新安全漏洞,可能导致 Web 应用面临 ** 未授权远程代码执行(RCE)** 风险。该漏洞编号为 CVE-2025-14894,CVSS 评分为 7.5,表明其对使用该组件的开发者和企业构成重大威胁。
漏洞的核心在于文件管理器处理上传数据的方式。根据 CERT/CC 的安全公告,该组件没有对用户上传的文件进行充分校验
“LivewireFilemanager 的 Component.php… 没有执行文件类型和 MIME 验证,允许通过上传恶意 PHP 文件实现 RCE。”
在典型攻击场景中,威胁 actor 可以将恶意 PHP 脚本伪装成正常文件上传。由于应用没有验证文件类型,它会被接受。如果服务器配置为公开访问这些文件—— 特别是执行过常见的 php artisan storage:link 命令 —— 攻击者只需访问该文件的 URL 即可触发执行。
“这使得攻击者能够创建恶意 PHP 文件、上传到应用,然后强制应用执行它,从而在目标设备上实现未授权任意代码执行。”
该漏洞之所以特别危险,是因为它利用了 Laravel 环境中 “非常常见的部署步骤”。漏洞说明指出,虽然 Livewire Filemanager 的开发者认为文件验证 “不在其范围内”,属于用户的责任,但默认行为加上标准 Laravel 配置,就形成了一条直接的攻击路径。
成功利用该漏洞的后果非常严重。攻击者能够以 Web 服务器用户权限 执行任意代码。
“该漏洞允许未授权攻击者以 Web 服务器用户身份执行代码,从而能够完全读写该用户可访问的所有文件,并进一步横向移动、攻陷其他设备。”
截至公告发布时,官方尚未发布补丁。报告还指出工具开发者的回应令人担忧:“在撰写本文时,厂商尚未确认该漏洞。”
在正式修复发布之前,安全团队应立即采取防御措施。CERT/CC 建议管理员检查其应用是否公开提供存储文件访问。
“CERT/CC 建议谨慎使用 Laravel Filemanager,并检查是否曾执行过 php artisan storage:link 命令。如果已执行,应考虑移除该工具的 Web 访问能力。”

Livewire Filemanager(一个在 Laravel PHP 框架中广泛使用的文件管理工具)中被发现了一个严重的新安全漏洞,可能导致 Web 应用面临 ** 未授权远程代码执行(RCE)** 风险。该漏洞编号为 CVE-2025-14894,CVSS 评分为 7.5,表明其对使用该组件的开发者和企业构成重大威胁。
漏洞的核心在于文件管理器处理上传数据的方式。根据 CERT/CC 的安全公告,该组件没有对用户上传的文件进行充分校验
“LivewireFilemanager 的 Component.php… 没有执行文件类型和 MIME 验证,允许通过上传恶意 PHP 文件实现 RCE。”
在典型攻击场景中,威胁 actor 可以将恶意 PHP 脚本伪装成正常文件上传。由于应用没有验证文件类型,它会被接受。如果服务器配置为公开访问这些文件—— 特别是执行过常见的 php artisan storage:link 命令 —— 攻击者只需访问该文件的 URL 即可触发执行。
“这使得攻击者能够创建恶意 PHP 文件、上传到应用,然后强制应用执行它,从而在目标设备上实现未授权任意代码执行。”
该漏洞之所以特别危险,是因为它利用了 Laravel 环境中 “非常常见的部署步骤”。漏洞说明指出,虽然 Livewire Filemanager 的开发者认为文件验证 “不在其范围内”,属于用户的责任,但默认行为加上标准 Laravel 配置,就形成了一条直接的攻击路径。
成功利用该漏洞的后果非常严重。攻击者能够以 Web 服务器用户权限 执行任意代码。
“该漏洞允许未授权攻击者以 Web 服务器用户身份执行代码,从而能够完全读写该用户可访问的所有文件,并进一步横向移动、攻陷其他设备。”
截至公告发布时,官方尚未发布补丁。报告还指出工具开发者的回应令人担忧:“在撰写本文时,厂商尚未确认该漏洞。”
在正式修复发布之前,安全团队应立即采取防御措施。CERT/CC 建议管理员检查其应用是否公开提供存储文件访问。
“CERT/CC 建议谨慎使用 Laravel Filemanager,并检查是否曾执行过 php artisan storage:link 命令。如果已执行,应考虑移除该工具的 Web 访问能力。”

是的,PHP 拥有光明的未来。各位看官可能会觉得这是玩笑,但您别急,且听我扯几句。这不是标题党,也不是哗众取宠。这是楼主近几天实实在在的有感而发。

这一切源于最近我家小朋友有了编程的兴趣;在尝试学第一门编程语言。让我意想不到的是,他选择了 PHP 。我很惊讶,PHP 不是没落了吗?大家讨论的都是 JS ,Go ,Rust ,Python 等等热门语言,按理说小孩网上怎么搜也不会蹦出 PHP 这三个字母吧。令我更意想不到的是,他学得津津有味。而且已经有了一些成果。观察几天后,我才发现,这一切并非偶然。

最重要一点因素,是 PHP 有最友好的社区,没有之一。不管是内外网,PHP 社区有极高的包容度。PHP 的讨论区很少有无谓的争吵,虚荣的推销。相反,PHP 社区有很多在其他圈子少见的谦逊与耐心 — 这也是我小孩喜欢网上讨论 PHP 的关键因素:当其他社区因为一个语法糖,一个框架,一个包争得面红耳赤时,经验丰富的 PHP 程序员却愿意放下姿态去回答几岁小孩的入门问题。进入 Zig ,Rust 等等社区,你会看到如邪教一般的传道与重写,我一个大人都有点承受不住。为了小孩的身心健康,我打心底更愿意小孩在 PHP 社区成长。

另外,不管喜不喜欢这门语言,少有人会否认 PHP 一直是一门及其实用且稳定的语言。尤其在 web 1.0 时代,PHP 绝对是指哪打哪的大杀器。哪怕是今天,快速迭代一个中小型全栈项目,很多人都会拿起 Laravel/ThinkPHP 。而现代化的 PHP 8 更是吸收了各家所长,OOP ,函数式,协程,可以说要什么有什么。更难能可贵的是在快速迭代的同时依然保持了高度的兼容性。对比乱成一锅粥的 Node/JS ,小孩写的 PHP 代码,不管是老语法,还是旧框架,往往都能运行,正向反馈频繁。我相信现在这些代码 5 年后依然能正常运行。

看到这里,您可能就明白我为什么说 PHP 有光明的未来了。后浪推前浪,世界终归是我们下一代的。当孩子们选择了 PHP ,他们怎么不会再一次为 PHP 带来阳光呢。

— 于 PHP 8.5 发布日

流量统计功能文档


仓库地址:https://gitee.com/teanary/teanary_service

目录

功能概述

流量统计功能用于统计网站前台的访问数据,包括真人访问和爬虫访问。系统会自动区分访问者类型,并记录详细的访问信息,帮助管理员了解网站的访问情况。

主要功能

  • ✅ 自动统计前台访问流量
  • ✅ 区分真人访问和爬虫访问
  • ✅ 识别爬虫来源(Google、Bing、Baidu等)
  • ✅ 缓存数据,批量写入数据库(每5分钟)
  • ✅ 自动清理过期数据(默认保留90天)
  • ✅ 提供统计看板和详细列表页面

功能特性

1. 智能过滤

系统会自动排除以下请求:

  • ❌ 管理后台(/manager/*
  • ❌ 个人中心(/user/*
  • ❌ API 路由(/api/*
  • ❌ 静态资源(.css, .js, .jpg, .png 等)
  • ❌ 非 GET 请求

2. 爬虫识别

系统能够识别以下类型的爬虫:

搜索引擎爬虫:

  • Google (Googlebot)
  • Bing (Bingbot)
  • Baidu (Baiduspider)
  • Yandex (Yandexbot)
  • Yahoo (Slurp)
  • DuckDuckGo (Duckduckbot)
  • Sogou (Sogou)

社交媒体爬虫:

  • Facebook (Facebookexternalhit)
  • Twitter (Twitterbot)
  • LinkedIn (Linkedinbot)
  • Pinterest (Pinterestbot)

其他爬虫:

  • Semrush (Semrushbot)
  • Ahrefs (Ahrefsbot)
  • Majestic (Mj12bot)
  • Dotbot
  • 以及其他通用爬虫(bot、crawler、spider等)

3. 数据记录

每条流量记录包含以下信息:

  • 路径 (path): 访问的页面路径
  • 方法 (method): HTTP 方法(通常为 GET)
  • IP 地址 (ip): 访问者的 IP 地址
  • 用户代理 (user_agent): 浏览器或爬虫的用户代理字符串
  • 来源页面 (referer): 来源页面的 URL
  • 语言 (locale): 访问时使用的语言代码
  • 是否爬虫 (is_bot): 是否为爬虫访问
  • 爬虫来源 (spider_source): 爬虫的具体来源(如 google、bing 等)
  • 访问次数 (count): 同一分钟内相同路径的访问次数
  • 统计时间 (stat_date): 统计日期(精确到分钟)

技术架构

数据流程

用户访问 → TrackTraffic 中间件 → 缓存数据 → 批量写入队列 → 数据库

核心组件

  1. 中间件 (TrackTraffic)

    • 位置:app/Http/Middleware/TrackTraffic.php
    • 功能:拦截请求,记录流量数据到缓存
  2. 批量写入任务 (BatchWriteTrafficStatsJob)

    • 位置:app/Jobs/BatchWriteTrafficStatsJob.php
    • 功能:每5分钟批量将缓存数据写入数据库
  3. 数据清理命令 (CleanOldTrafficStats)

    • 位置:app/Console/Commands/CleanOldTrafficStats.php
    • 功能:清理超过指定天数的历史数据
  4. 数据模型 (TrafficStatistic)

    • 位置:app/Models/TrafficStatistic.php
    • 功能:定义数据结构和查询方法
  5. 管理界面

    • 统计看板:app/Filament/Manager/Pages/TrafficStatistics.php
    • 详细列表:app/Filament/Manager/Resources/TrafficStatisticResource.php

缓存机制

  • 使用 Laravel Cache 存储临时流量数据
  • 缓存键格式:traffic:queue:Y-m-d-H-i
  • 缓存过期时间:1小时
  • 每5分钟批量写入一次数据库

配置说明

1. 中间件注册

中间件已在 routes/web.php 中注册:

Route::prefix('{locale}')->middleware([
    SetLocaleAndCurrency::class, 
    \App\Http\Middleware\TrackTraffic::class
])->group(function () {
    // 前台路由
});

2. 定时任务配置

routes/console.php 中已配置:

// 流量统计批量写入任务(每5分钟执行一次)
Schedule::command('app:batch-write-traffic-stats --queue')
    ->everyFiveMinutes()
    ->withoutOverlapping()
    ->runInBackground();

// 流量统计数据清理任务(每天凌晨2点执行,清理90天前的数据)
Schedule::command('app:clean-old-traffic-stats')
    ->dailyAt('02:00')
    ->withoutOverlapping();

3. 数据库表结构

表名:traffic_statistics

主要字段:

  • id: 主键(雪花ID)
  • path: 访问路径(索引)
  • method: HTTP 方法(索引)
  • ip: IP 地址(索引)
  • user_agent: 用户代理
  • referer: 来源页面
  • locale: 语言代码(索引)
  • is_bot: 是否为爬虫(索引)
  • spider_source: 爬虫来源(索引)
  • count: 访问次数
  • stat_date: 统计时间(索引,精确到分钟)

使用方法

1. 查看统计看板

  1. 登录管理后台
  2. 导航到 统计流量统计看板
  3. 可以查看:

    • 总访问量、页面浏览量、独立IP、独立页面
    • 真人访问和爬虫访问的对比
    • 热门页面 Top 20
  4. 支持筛选:

    • 日期范围:今天、昨天、最近7天、最近30天、最近90天
    • 访问者类型:全部、真人访问、爬虫访问

2. 查看详细列表

  1. 登录管理后台
  2. 导航到 统计流量明细
  3. 可以查看每条访问记录的详细信息
  4. 支持筛选:

    • 访问类型(真人/爬虫)
    • 爬虫来源
    • 日期范围

3. 手动触发批量写入

如果需要立即将缓存数据写入数据库,可以执行:

php artisan app:batch-write-traffic-stats

4. 手动清理数据

清理超过指定天数的数据:

# 清理90天前的数据(默认)
php artisan app:clean-old-traffic-stats

# 清理30天前的数据
php artisan app:clean-old-traffic-stats --days=30

# 清理180天前的数据
php artisan app:clean-old-traffic-stats --days=180

数据管理

数据保留策略

  • 默认保留时间:90天
  • 清理时间:每天凌晨2点自动执行
  • 清理方式:分批删除,每批1000条记录

数据统计方法

获取指定时间范围内的统计数据
use App\Models\TrafficStatistic;
use Illuminate\Support\Carbon;

// 获取最近7天的所有数据
$startDate = Carbon::today()->subDays(6);
$endDate = Carbon::today()->endOfDay();
$stats = TrafficStatistic::getStatsByDateRange($startDate, $endDate);

// 只获取真人访问数据
$humanStats = TrafficStatistic::getStatsByDateRange($startDate, $endDate, false);

// 只获取爬虫访问数据
$botStats = TrafficStatistic::getStatsByDateRange($startDate, $endDate, true);
获取热门页面
// 获取最近7天的热门页面 Top 10
$topPages = TrafficStatistic::getTopPages($startDate, $endDate, 10);

// 只获取真人访问的热门页面
$topHumanPages = TrafficStatistic::getTopPages($startDate, $endDate, 10, false);

// 只获取爬虫访问的热门页面
$topBotPages = TrafficStatistic::getTopPages($startDate, $endDate, 10, true);

常见问题

Q1: 为什么有些访问没有被统计?

A: 系统会自动排除以下请求:

  • 管理后台和个人中心的访问
  • API 路由
  • 静态资源文件
  • 非 GET 请求

如果您的访问路径符合以上条件,将不会被统计。

Q2: 数据多久写入一次数据库?

A: 系统每5分钟自动批量写入一次。如果需要立即写入,可以手动执行 php artisan app:batch-write-traffic-stats 命令。

Q3: 如何修改数据保留时间?

A: 有两种方式:

  1. 修改定时任务:编辑 routes/console.php,修改 --days 参数
  2. 手动执行:执行 php artisan app:clean-old-traffic-stats --days=天数

Q4: 爬虫识别不准确怎么办?

A: 可以修改 app/Http/Middleware/TrackTraffic.php 中的 isBot()getSpiderSource() 方法,添加或修改爬虫识别规则。

Q5: 如何查看缓存中的数据?

A: 可以使用 Laravel Tinker:

php artisan tinker

然后执行:

// 查看某个时间点的队列
Cache::get('traffic:queue:2026-01-17-14-30');

// 查看所有流量相关的缓存键(需要 Redis)
Redis::keys('traffic:*');

Q6: 数据量很大,会影响性能吗?

A: 系统采用了以下优化措施:

  • 使用缓存暂存数据,减少数据库写入频率
  • 批量写入,每5分钟写入一次
  • 使用索引优化查询性能
  • 自动清理过期数据,控制数据量

如果数据量仍然很大,可以考虑:

  • 缩短数据保留时间
  • 增加批量写入频率
  • 优化数据库索引

Q7: 如何禁用流量统计?

A:routes/web.php 中移除 TrackTraffic::class 中间件即可。

Q8: 可以统计其他路径吗?

A: 可以修改 app/Http/Middleware/TrackTraffic.php 中的 shouldTrack() 方法,调整过滤规则。

相关文件

  • 中间件:app/Http/Middleware/TrackTraffic.php
  • 批量写入任务:app/Jobs/BatchWriteTrafficStatsJob.php
  • 清理命令:app/Console/Commands/CleanOldTrafficStats.php
  • 数据模型:app/Models/TrafficStatistic.php
  • 统计看板:app/Filament/Manager/Pages/TrafficStatistics.php
  • 详细列表:app/Filament/Manager/Resources/TrafficStatisticResource.php
  • 数据库迁移:database/migrations/2026_01_17_204550_create_traffic_statistics_table.php

更新日志

2026-01-17

  • ✅ 初始版本发布
  • ✅ 支持真人/爬虫区分
  • ✅ 支持爬虫来源识别
  • ✅ 自动批量写入和清理

文档版本:1.0
最后更新:2026-01-17

是的,PHP 拥有光明的未来。各位看官可能会觉得这是玩笑,但您别急,且听我扯几句。这不是标题党,也不是哗众取宠。这是楼主近几天实实在在的有感而发。

这一切源于最近我家小朋友有了编程的兴趣;在尝试学第一门编程语言。让我意想不到的是,他选择了 PHP 。我很惊讶,PHP 不是没落了吗?大家讨论的都是 JS ,Go ,Rust ,Python 等等热门语言,按理说小孩网上怎么搜也不会蹦出 PHP 这三个字母吧。令我更意想不到的是,他学得津津有味。而且已经有了一些成果。观察几天后,我才发现,这一切并非偶然。

最重要一点因素,是 PHP 有最友好的社区,没有之一。不管是内外网,PHP 社区有极高的包容度。PHP 的讨论区很少有无谓的争吵,虚荣的推销。相反,PHP 社区有很多在其他圈子少见的谦逊与耐心 — 这也是我小孩喜欢网上讨论 PHP 的关键因素:当其他社区因为一个语法糖,一个框架,一个包争得面红耳赤时,经验丰富的 PHP 程序员却愿意放下姿态去回答几岁小孩的入门问题。进入 Zig ,Rust 等等社区,你会看到如邪教一般的传道与重写,我一个大人都有点承受不住。为了小孩的身心健康,我打心底更愿意小孩在 PHP 社区成长。

另外,不管喜不喜欢这门语言,少有人会否认 PHP 一直是一门及其实用且稳定的语言。尤其在 web 1.0 时代,PHP 绝对是指哪打哪的大杀器。哪怕是今天,快速迭代一个中小型全栈项目,很多人都会拿起 Laravel/ThinkPHP 。而现代化的 PHP 8 更是吸收了各家所长,OOP ,函数式,协程,可以说要什么有什么。更难能可贵的是在快速迭代的同时依然保持了高度的兼容性。对比乱成一锅粥的 Node/JS ,小孩写的 PHP 代码,不管是老语法,还是旧框架,往往都能运行,正向反馈频繁。我相信现在这些代码 5 年后依然能正常运行。

看到这里,您可能就明白我为什么说 PHP 有光明的未来了。后浪推前浪,世界终归是我们下一代的。当孩子们选择了 PHP ,他们怎么不会再一次为 PHP 带来阳光呢。

— 于 PHP 8.5 发布日