请问下,用PHP获取浏览当前用户的公网IP地址,用什么方法啊?

请问下,用PHP获取浏览当前用户的IP地址,用什么方法啊?
我查了一下,都说是用$_SERVER['REMOTE_ADDR'],但是这个获取的结果并不是公网IP呀.

阅读 4k
4 个回答

实际上,你没有办法真的能保证你获取到的一定是当前用户的公网ip。
我们常用的几个头
REMOTE_ADDR 这个头是安全的,但是他是当前节点的上一跳连接的IP,在现在的复杂网络下,这个头很难直接用。
X-FORWARDED-FOR 这个头是不安全的,因为用户可以伪造,这个头得逻辑是 如果当前服务器是代理,就把当前服务器拿到的remote_addr ip加到 x-forwarded-for 这个头的尾部,但是没有办法保证,这个头里面的已有的ip到底是用户自己发过来的还是代理服务器发过来的。
client-ip 这个是一些web服务器提供的功能,逻辑实现可能不一致,大概就是如果有x-forwarded-for,就取最早的一个合法ip,如果没有,就取remote_addr。

所以,你只能取你信任的IP前的一个ip。比如,你使用了CDN,那么你只能信任CDN节点IP的前一个IP(CDN节点ip有白名单,当然,你也可以让CDN把客户ip用特殊的头发给你),如果没有使用CDN,那么,你能信任的只有Remote_addr 或者,你的入口反向代理服务器获取的remote_addr

$_SERVER['REMOTE_ADDR'] 获取的是浏览当前用户的ip地址,也就是服务器获取访问客户端的ip
如果是使用本地或局域网测试肯定就不是了公网ip地址了

public function ip($type = 0, $adv = true)

{
    $type      = $type ? 1 : 0;
    static $ip = null;

    if (null !== $ip) {
        return $ip[$type];
    }

    if ($adv) {
        if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
            $arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
            $pos = array_search('unknown', $arr);
            if (false !== $pos) {
                unset($arr[$pos]);
            }
            $ip = trim(current($arr));
        } elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
            $ip = $_SERVER['HTTP_CLIENT_IP'];
        } elseif (isset($_SERVER['REMOTE_ADDR'])) {
            $ip = $_SERVER['REMOTE_ADDR'];
        }
    } elseif (isset($_SERVER['REMOTE_ADDR'])) {
        $ip = $_SERVER['REMOTE_ADDR'];
    }

    // IP地址合法验证
    $long = sprintf("%u", ip2long($ip));
    $ip   = $long ? [$ip, $long] : ['0.0.0.0', 0];

    return $ip[$type];
}

直接拿去用

依次检测以下请求头,如果有值就返回

  1. REMOTE_ADDR
  2. X-FORWARDED-FOR
  3. X-REAL-IP
  4. HTTP_CLIENT_IP
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题