ThinkPHP5 获取 Header 应优先用 $request->header(),但 Authorization、X-Forwarded-For 等字段需通过 $_SERVER['HTTP_AUTHORIZATION'] 或 input('server.HTTP_X_FORWARDED_FOR') 获取,因 TP5 会将 header 名标准化为小写下划线格式且 Nginx 默认过滤含大写/连字符的 HTTP_ 变量。

直接说结论:ThinkPHP5 中获取 Header 信息,优先用 $request->header(),但遇到 Authorization、X-Forwarded-For 等大小写敏感或带连字符的字段时,必须改用 $_SERVER['HTTP_AUTHORIZATION'] 或 input('server.HTTP_X_FORWARDED_FOR'),否则大概率拿不到值。
request()->header() 返回的 key 全是小写下划线,不是原始 header 名
ThinkPHP5 内部会对所有 header 名做标准化处理:把 Content-Type → content_type,X-Requested-With → x_requested_with,Accept-Encoding → accept_encoding。所以:
-
$request->header('content_type')能取到Content-Type的值 -
$request->header('Content-Type')或$request->header('CONTENT_TYPE')都返回null - 自定义 header 如
X-Api-Version会被转成x_api_version,调用时得用这个键名 - 这种转换是单向的——你无法从
header()结果里还原原始 header 大小写或符号
Authorization 和 X-* 类 header 在 Nginx + PHP-FPM 下经常为空
这是因为 CGI/FastCGI 环境默认会过滤掉以 HTTP_ 开头但含大写字母或特殊符号的 $_SERVER 变量,比如 HTTP_AUTHORIZATION 被直接丢弃。Nginx 不像 Apache 那样原生支持 apache_request_headers(),所以:
- 必须在 Nginx 配置中显式透传:
fastcgi_param HTTP_AUTHORIZATION $http_authorization; - 同理,若用
X-Real-IP或X-Forwarded-For,也要加fastcgi_param HTTP_X_REAL_IP $http_x_real_ip; - 不配这行,
$_SERVER['HTTP_AUTHORIZATION']就是空,$request->header('authorization')也拿不到 - ThinkPHP5 没有
request()->server('HTTP_AUTHORIZATION')这种封装(那是 TP6+ 才有的),只能手动兜底
获取全部 header 的兼容写法要兼顾 Apache 和 Nginx
TP5 的 $request->header() 底层其实做了环境适配,但如果你需要原始未标准化的全量 header(比如做签名验证、调试代理链),就不能只依赖它。推荐手写一个兼容函数:
立即学习“PHP免费学习笔记(深入)”;
function getRawHeaders() {
$headers = [];
if (function_exists('apache_request_headers')) {
$headers = apache_request_headers();
} else {
foreach ($_SERVER as $key => $val) {
if (strpos($key, 'HTTP_') === 0) {
$name = str_replace('_', '-', strtolower(substr($key, 5)));
$headers[$name] = $val;
}
}
}
return $headers;
}注意点:
-
apache_request_headers()只在 Apache 模块下有效,Nginx 下必然失败 -
$_SERVER方案在 CLI 环境下无意义(没有 HTTP 上下文),别在命令行里测 header - 该函数返回的 key 是标准 HTTP 格式(如
authorization、x-forwarded-for),和原始请求头一致
真实 IP 获取和 header 透传强相关,不能只靠 request()->ip()
$request->ip() 默认只读 $_SERVER['REMOTE_ADDR'],在 Nginx + PHP-FPM 架构中这个值永远是 Nginx 的内网地址(比如 127.0.0.1),不是用户真实 IP。要拿到真实 IP,必须依赖反向代理透传的 header:
- Nginx 需配置:
proxy_set_header X-Real-IP $remote_addr;和proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - 然后在代码里用:
$_SERVER['HTTP_X_REAL_IP']或$request->header('x_real_ip') - TP5 不支持可信代理白名单机制(那是 TP6 的
trust_proxy配置),所以不要指望$request->ip(true)能自动识别可信代理 - 如果前端经过多层代理,
X-Forwarded-For是逗号分隔的 IP 列表,最左边才是用户真实 IP,需自行explode(',', $ipStr)[0]提取
真正麻烦的地方不在语法,而在于 Web 服务器配置和 PHP 运行模式的耦合——同一段 $request->header('authorization'),在 Apache 下可能正常,在 Nginx 下就静默失败。动手前先确认部署环境,比查文档更重要。



















