request()->header() 是 thinkphp 6 中间件读取请求头的标准方式,不区分大小写且自动转换下划线为短横线,但返回 null 而非空字符串,需手动判空;nginx 需开启 underscores_in_headers on 才能透传自定义头。

中间件里用 request()->header() 最直接
ThinkPHP 6 的中间件中,request()->header() 是读取请求头的标准方式,它不区分大小写,也兼容下划线转短横线(比如 user-agent、User-Agent、USER_AGENT 都能拿到值)。但要注意:它返回的是原始字符串,不做空值处理——如果前端没发某个头,结果就是 null,不是空字符串。
常见错误是直接用:$ua = request()->header('user-agent'); 然后直接存库或打印,结果日志里一堆 Notice: Trying to get property of non-object 或数据库字段被 NULL 填满。
- 必须手动判空:
if (!$ua = request()->header('user-agent')) { $ua = 'unknown'; } - 若需截断长度(如防超长 UA 溢出字段),用
mb_substr($ua, 0, 128),别用substr,否则中文会乱码 - CLI 或 Swoole 长连接环境下,
$_SERVER['HTTP_USER_AGENT']可能根本不存在,request()->header()就会返回null,得有兜底
request()->header() 在中间件执行时机很关键
中间件分「前置」和「后置」两个阶段:前置在 $next($request) 之前,后置在之后。如果你只是读头、不改逻辑,前置就够了;但若要基于头做路由跳转、权限拦截,就得在前置阶段完成判断并提前 return。
例如识别微信小程序,不能等控制器才处理——401/404 请求根本进不了控制器,UA 就漏统计了。
- UA 提取、解析、归类必须放在中间件
handle()开头,而不是控制器里 - 解析结果建议存到请求属性:
$request->withAttr('ua_type', 'wxapp'),后续所有模块都统一读$request->attr('ua_type') - 别在中间件里调
request()->isPost()这类方法来间接推头——它内部也是读REQUEST_METHOD,不如直接$request->method() === 'POST'明确
读自定义头(如 X-App-ID)和标准头没区别,但注意 Nginx 是否透传
ThinkPHP 能读到的头,完全取决于 Web 服务器是否把它们传进来。Nginx 默认会过滤掉带下划线的头(如 X_App_ID),而 PHP 又会把短横线转成下划线(X-App-ID → HTTP_X_APP_ID),这个链路一断就读不到。
- 确保 Nginx 配置里有:
underscores_in_headers on;(否则X-App-ID会被丢弃) - PHP-FPM 环境下,还要检查
fastcgi_param是否显式传递,比如:fastcgi_param HTTP_X_APP_ID $http_x_app_id; - 读的时候仍用小写+短横线写法:
request()->header('x-app-id'),TP 内部会自动映射 - 不要依赖
$_SERVER['HTTP_X_APP_ID'],它在 CLI/Swoole 下不稳定,request()->header()才是统一入口
为什么有时读不到 Origin 头?跨域预检场景要特别小心
浏览器发跨域请求时,Origin 头只在非简单请求(如带 Authorization、Content-Type: application/json)的预检(OPTIONS)和主请求中携带。但有些代理或 CDN 会把它删掉,导致白名单匹配失败。
- 读
$origin = $request->header('origin')前,先确认请求确实是跨域发起的(比如$request->isOptions()为 true) - 生产环境务必从配置读白名单:
config('cors.allow_origins'),内容必须是完整协议+域名+端口(https://admin.example.com),不能只写admin.example.com - 如果
$origin不在白名单里,就别设Access-Control-Allow-Origin,否则浏览器仍会拦截——宁可不响应,也不能错设
真正容易被忽略的是:Origin 头不是“总会存在”,它由浏览器控制,且可能被中间层剥离。读不到时,别急着改代码,先抓包看请求发出时有没有、走到 TP 前有没有被 Nginx 吃掉。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











