«

PHP获取客户端IP

时间:2026-10-20 07:19     作者:emer     分类: 无


PHP获取客户端IP

引言

记录访问日志、做地域统计或IP限定时要拿真实访客IP。经过Nginx反代或CDN后,REMOTE_ADDR是代理地址,真实IP藏在转发头里,直接取单一字段容易拿到代理IP,需要按可信链兜底并校验。

直连场景

$ip = $_SERVER['REMOTE_ADDR'] ?? '';

没有反代时,这就是直连客户端IP。

反代后取真实IP

$headers = [
    'HTTP_X_FORWARDED_FOR',
    'HTTP_X_REAL_IP',
    'HTTP_CLIENT_IP',
];
foreach ($headers as $h) {
    if (!empty($_SERVER[$h])) {
        $ip = explode(',', $_SERVER[$h])[0];
        break;
    }
}

X-Forwarded-For可能是逗号分隔的IP链,取第一个才是原始客户端。

封装函数

function getClientIp(): string {
    foreach (['HTTP_X_FORWARDED_FOR','HTTP_X_REAL_IP'] as $h) {
        if (!empty($_SERVER[$h])) {
            $ip = trim(explode(',', $_SERVER[$h])[0]);
            if (filter_var($ip, FILTER_VALIDATE_IP)) return $ip;
        }
    }
    return $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0';
}

filter_var校验格式,非法就回退到REMOTE_ADDR。

代理头必须由服务端写入

proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

头要由可信Nginx设置,不能完全信任客户端自带。

注意事项

总结

直连取REMOTE_ADDR,反代后从X-ForwardedFor、X-Real-IP按序兜底,XFF逗号链取第一个,filter_var校验后回退,代理头由可信Nginx写入。关键是客户端可伪造转发头,只信任自己配置的代理链,IP适合统计不适合单独做安全判定,CDN需用厂商回源头。

标签: PHP 客户端ip REMOTE_ADDR X-Forwarded-For 反代