在 PHP 中获取访客 IP 地址看似简单,但由于用户可能通过、CDN 或负载均衡器访问网站,直接使用 $_SERVER['REMOTE_ADDR'] 并不总是准确。因此,需要综合多个 HTTP 头信息来更可靠地判断真实客户端 IP。
以下是一个可靠的封装函数,用于获取访客的真实 IP 地址:
<?php
function get_client_ip() {
// 优先级顺序:从最可信到最不可信
$ip_keys = [
'HTTP_CLIENT_IP', // 客户端IP(较少使用)
'HTTP_X_FORWARDED_FOR', // 经过的IP列表
'HTTP_X_FORWARDED', // 类似上一个
'HTTP_X_CLUSTER_CLIENT_IP', // 负载均衡集群中的客户端IP
'HTTP_FORWARDED_FOR', // 旧式头
'HTTP_FORWARDED', // 同上
'HTTP_CF_CONNECTING_IP', // Cloudflare CDN
'HTTP_TRUE_CLIENT_IP', // 部分CDN(如阿里云)
'REMOTE_ADDR' // 最后兜底:直接连接的IP
];
foreach ($ip_keys as $key) {
if (!isset($_SERVER[$key]) || empty($_SERVER[$key])) {
continue;
}
// 获取IP字符串
$ip_list = explode(',', $_SERVER[$key]);
// 遍历IP列表,从左到右取第一个合法公网IP(排除私有IP和保留IP)
foreach ($ip_list as $ip) {
$ip = trim($ip);
// 过滤私有/保留IP地址
if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RESv4_RANGE)) {
return $ip;
}
}
}
// 兜底返回本地地址(理论上不会走到这里)
return '127.0.0.1';
}
// 使用示例:
$client_ip = get_client_ip();
echo "访客IP: " . $client_ip;
🔍 函数说明
| 头字段 | 说明 |
|---|---|
HTTP_CLIENT_IP |
某些设置的客户端IP |
HTTP_X_FORWARDED_FOR |
常见/CDN 添加的原始IP列表 |
HTTP_CF_CONNECTING_IP |
Cloudflare 特有的头 |
REMOTE_ADDR |
直接连接的服务器端看到的IP |
⚠️ 注意:
X-Forwarded-For可被伪造,仅当你的应用部署在可信后方时才可信任。
✅ 安全建议
-
不要盲目信任所有头信息
攻击者可以伪造X-Forwarded-For等头。如果你的应用暴露在公网,应只信任来自可信或 CDN 的头。 -
结合实际架构过滤
如果你使用了 Nginx + PHP-FPM,并且 Nginx 已经设置了可信,可以在 Nginx 中统一设置头,PHP 只读取特定头。示例 Nginx 配置:
location ~ .php$ { include fastcgi_params; fastcgi_param HTTP_X_FORWARDED_FOR $proxy_add_x_forwarded_for; fastcgi_param REMOTE_ADDR $proxy_add_x_forwarded_for; fastcgi_pass unix:/var/run/php/php8.1-fpm.sock; } -
记录日志时建议同时记录所有来源IP,便于排查问题:
$log_data = [ 'real_ip' => get_client_ip(), 'remote_addr' => $_SERVER['REMOTE_ADDR'] ?? '', 'x_forwarded_for' => $_SERVER['HTTP_X_FORWARDED_FOR'] ?? '', ];
🧪 测试示例
你可以用 curl 模拟请求测试:
curl -H "X-Forwarded-For: 1.2.3.4, 5.6.7.8" http://yoursite.com/test.php
函数会尝试从 X-Forwarded-For 中提取第一个合法公网 IP。
✅ 总结
这个函数通过:
- 多个头部兼容性支持;
- 排除私有/保留IP;
- 返回最可能真实的客户端IP;
是目前在通用场景下较为可靠的获取访客 IP 的方式。
💡 提示:在高安全要求场景中,建议结合防火墙、WAF 和日志分析系统共同识别真实用户 IP。
云计算HECS