request()->ip()最直接但不可靠,必须配置trusted_proxies并配合nginx正确设置x-real-ip,否则默认返回代理ip;手动解析x-forwarded-for需取最后一个合法非私有ip,且始终校验ip格式与可信性。

request()->ip() 是最直接、推荐的方式,但它默认不校验代理头,直连时可用,有 Nginx/SLB/CDN 时大概率返回代理 IP。是否可靠,取决于你部署环境和 trusted_proxies 配置。
request()->ip() 默认行为与可信代理配置
ThinkPHP 5+ 的 request()->ip() 底层调用的是 think\Request 类的 ip() 方法,它会按顺序检查:HTTP_X_FORWARDED_FOR → HTTP_X_REAL_IP → REMOTE_ADDR,但**仅当设置了可信代理列表后,才会信任并解析 X-Forwarded-For 等头**。
否则,它会跳过所有代理头,直接返回 REMOTE_ADDR(即上一跳代理的 IP,不是真实客户端)。
- 必须在配置中显式声明可信代理段,例如 Nginx 回源 IP、阿里云 SLB 内网段、公司内网网段
- 配置位置:
config/request.php或应用配置目录下新增该文件,内容为:return [ 'trust_proxies' => ['10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16', '127.0.0.1'], ]; - 若使用 Swoole 或 Workerman 部署,
trust_proxies不生效,需手动处理头信息
get_client_ip() 函数的兼容性陷阱
ThinkPHP 自带的全局函数 get_client_ip() 行为较老,**默认不校验 IP 合法性,且对 X-Forwarded-For 取第一个值(易被伪造)**,在新版框架中已不推荐直接使用。
- 它不会自动识别
X-Real-IP,除非你重写了该函数 - 参数
$type=1返回的是ip2long()结果,注意是无符号整型,PHP 7+ 中需用sprintf('%u', ip2long($ip))才能跨平台一致 - 若未做合法性过滤(如
filter_var($ip, FILTER_VALIDATE_IP)),可能返回unknown、空字符串甚至恶意构造的 IP
手动解析 X-Forwarded-For 获取真实客户端 IP
当你无法控制代理配置,或需要更精细控制(比如只取最后一个非私有 IP),应绕过框架封装,手动读取并清洗头信息。
-
X-Forwarded-For值形如"203.201.10.5, 10.10.10.10, 127.0.0.1",真实客户端 IP 是**最后一个非私有、非保留地址**(不是第一个) - 必须排除
127.0.0.1、10.0.0.0/8、172.16.0.0/12、192.168.0.0/16、::1等 - 示例逻辑:
$xForwarded = $request->header('x-forwarded-for', ''); if ($xForwarded) { $ips = array_map('trim', explode(',', $xForwarded)); $clientIp = '0.0.0.0'; for ($i = count($ips) - 1; $i >= 0; $i--) { if (filter_var($ips[$i], FILTER_VALIDATE_IP) && !filter_var($ips[$i], FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) { $clientIp = $ips[$i]; break; } } }
为什么不能只依赖 REMOTE_ADDR
$_SERVER['REMOTE_ADDR'](即 $request->server('remote_addr'))永远是 TCP 连接发起方的 IP,在有反向代理时,它就是 Nginx、SLB 或 CDN 节点的内网 IP,**不是用户真实出口 IP**。
- 常见错误:在阿里云 SLB 后直接用
REMOTE_ADDR,得到的是类似100.64.x.x的地址(阿里云保留段) - CDN 场景下(如 Cloudflare、腾讯云 CDN),
REMOTE_ADDR是 CDN 边缘节点 IP,必须依赖CF-Connecting-IP或X-Real-IP头 - 即使没配代理,某些 NAT 环境(如企业出口网关)也可能导致
REMOTE_ADDR不唯一或不可靠
真实场景里,IP 获取不是“调一个函数就完事”,关键在于你能否确认请求链路上每一跳是否可信、头是否可篡改、IP 是否做过清洗。很多线上问题(如登录地域限制误判、风控规则失效)都源于这里没对齐信任边界。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











