PHP中如何可靠的获取访客IP地址,封装一个函数?

服务器

在 PHP 中,获取访客的真实 IP 地址并不总是简单的,因为用户可能通过X_X服务器、CDN 或者负载均衡器访问网站。为了尽可能准确地获取访客的原始 IP,你需要检查多个 HTTP 头部信息(如 HTTP_X_FORWARDED_FORHTTP_CLIENT_IP),同时也要注意防止伪造。

下面是一个可靠的封装函数,用于获取访客的真实 IP 地址:

<?php

function get_visitor_ip() {
    $ip = '';

    // 检查X_X头信息
    if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
        // 检查是否有客户端IP设置
        $ip = $_SERVER['HTTP_CLIENT_IP'];
    } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
        // 如果有多个IP,用逗号分隔,取第一个非未知IP
        $ipList = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
        foreach ($ipList as $proxyIp) {
            $proxyIp = trim($proxyIp);
            if (filter_var($proxyIp, FILTER_VALIDATE_IP)) {
                $ip = $proxyIp;
                break;
            }
        }
    } elseif (!empty($_SERVER['REMOTE_ADDR'])) {
        // 最后使用远程地址
        $ip = $_SERVER['REMOTE_ADDR'];
    }

    // 防止伪造:如果最终得到的是空IP或局域网IP,返回 UNKNOWN
    if (!$ip || !filter_var($ip, FILTER_VALIDATE_IP) || is_private_ip($ip)) {
        return 'UNKNOWN';
    }

    return $ip;
}

/**
 * 判断是否为私有IP(局域网IP)
 */
function is_private_ip($ip) {
    if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE)) {
        return false;
    }
    return true;
}

// 示例调用
echo '访客IP是:' . get_visitor_ip();

📌 函数说明:

  1. 优先级顺序

    • HTTP_CLIENT_IP
    • HTTP_X_FORWARDED_FOR
    • REMOTE_ADDR
  2. 安全性处理

    • 对每个 IP 进行合法性验证(filter_var(..., FILTER_VALIDATE_IP))。
    • 跳过局域网 IP(如 192.168.x.x、10.x.x.x、172.16.x.x–172.31.x.x)。
    • 如果所有方式都无法获取合法 IP,则返回 'UNKNOWN'
  3. 注意事项

    • HTTP_X_FORWARDED_FORHTTP_CLIENT_IP 是可以被客户端伪造的,不能完全信任。
    • 如果你使用 CDN(如 Cloudflare),请根据 CDN 的文档从特定头部(如 HTTP_CF_CONNECTING_IP)中获取真实 IP。
    • 在安全敏感场景(如登录日志、封禁 IP 等),建议结合数据库记录和行为分析进行判断。

✅ 示例输出:

访客IP是:192.0.2.1

如果你的应用部署在反向X_X或 CDN 后面,可以根据实际环境增加对以下头部的支持:

$_SERVER['HTTP_X_FORWARDED_FOR']
$_SERVER['HTTP_X_REAL_IP']
$_SERVER['HTTP_CF_CONNECTING_IP']  // Cloudflare
$_SERVER['HTTP_TRUE_CLIENT_IP']   // Cloudflare(启用时)

需要根据你的服务器架构做适当调整。


如有具体部署环境(如 Nginx + CDN),也可以提供,我可以帮你定制更精准的函数版本。

未经允许不得转载:CDNK博客 » PHP中如何可靠的获取访客IP地址,封装一个函数?