【问题标题】:Get the client IP address using PHP [duplicate]使用 PHP 获取客户端 IP 地址 [重复]
【发布时间】:2013-03-19 21:50:23
【问题描述】:

我想获取使用我网站的客户端 IP 地址。我正在使用 PHP $_SERVER superglobal:

$_SERVER['REMOTE_ADDR'];

但我发现它无法使用它提供正确的 IP 地址。我得到了我的 IP 地址,发现它与我的 IP 地址不同,我还可以在某些网站上看到我的 IP 地址,例如:

http://whatismyipaddress.com/

我粘贴了提供我的 PHP 功能的 IP 地址,但这个网站没有显示任何结果。请问这个问题是怎么来的,如何获取客户端的IP地址?

【问题讨论】:

  • 如果您在本地服务器上,情况会有所不同(例如:192.168.xxx.xxx),因为您从 whatsmyip 中检查您正在获取他们提供给您的 isp ip。
  • 在您的计算机上,您将看到您的私有 IP (192..),而在网站上,您将看到您的公共 IP (84...)。一般来说,您的公共 IP 是唯一有趣的。
  • 再一次,并不是真正的重复,因为这是谷歌排名最高的。 Stackoverflow 伙计们,加油。 “标记为重复”经常发生。如果这个排名更好,那是有充分理由的。谷歌已经发声了。

标签: php ip-address


【解决方案1】:

获取访问者/客户的IP address 的最简单方法是使用$_SERVER['REMOTE_ADDR']$_SERVER['REMOTE_HOST'] 变量。

但是,有时这不会返回访问者的正确 IP 地址,因此我们可以使用其他一些服务器变量来获取 IP 地址。

以下两个函数是等价的,不同之处仅在于检索值的方式和来源。

getenv() 用于在 PHP 中获取环境变量的值。

// Function to get the client IP address
function get_client_ip() {
    $ipaddress = '';
    if (getenv('HTTP_CLIENT_IP'))
        $ipaddress = getenv('HTTP_CLIENT_IP');
    else if(getenv('HTTP_X_FORWARDED_FOR'))
        $ipaddress = getenv('HTTP_X_FORWARDED_FOR');
    else if(getenv('HTTP_X_FORWARDED'))
        $ipaddress = getenv('HTTP_X_FORWARDED');
    else if(getenv('HTTP_FORWARDED_FOR'))
        $ipaddress = getenv('HTTP_FORWARDED_FOR');
    else if(getenv('HTTP_FORWARDED'))
       $ipaddress = getenv('HTTP_FORWARDED');
    else if(getenv('REMOTE_ADDR'))
        $ipaddress = getenv('REMOTE_ADDR');
    else
        $ipaddress = 'UNKNOWN';
    return $ipaddress;
}

$_SERVER 是一个数组,其中包含由 Web 服务器创建的服务器变量。

// Function to get the client IP address
function get_client_ip() {
    $ipaddress = '';
    if (isset($_SERVER['HTTP_CLIENT_IP']))
        $ipaddress = $_SERVER['HTTP_CLIENT_IP'];
    else if(isset($_SERVER['HTTP_X_FORWARDED_FOR']))
        $ipaddress = $_SERVER['HTTP_X_FORWARDED_FOR'];
    else if(isset($_SERVER['HTTP_X_FORWARDED']))
        $ipaddress = $_SERVER['HTTP_X_FORWARDED'];
    else if(isset($_SERVER['HTTP_FORWARDED_FOR']))
        $ipaddress = $_SERVER['HTTP_FORWARDED_FOR'];
    else if(isset($_SERVER['HTTP_FORWARDED']))
        $ipaddress = $_SERVER['HTTP_FORWARDED'];
    else if(isset($_SERVER['REMOTE_ADDR']))
        $ipaddress = $_SERVER['REMOTE_ADDR'];
    else
        $ipaddress = 'UNKNOWN';
    return $ipaddress;
}

【讨论】:

  • 请注意,此功能也可能会导致您非常错误。特别是,HTTP_X_FORWARDED_FOR 可以是客户端选择设置的任何内容,而 REMOTE_ADDR 更难伪造,如果客户端想要获得实际响应。
  • 另外,即使不是伪造的,也有很多设置只会填充客户端内部网络IP,这将是无用的。
  • 这段代码很容易被欺骗 小心你使用它的地方!
  • 您需要在被黑客入侵之前阅读此内容stackoverflow.com/questions/3003145/…
  • @huykon225 因为您在本地主机中。尝试在服务器上上传脚本。
【解决方案2】:

在 PHP 5.3 或更高版本中,您可以这样获取:

$ip = getenv('HTTP_CLIENT_IP')?:
getenv('HTTP_X_FORWARDED_FOR')?:
getenv('HTTP_X_FORWARDED')?:
getenv('HTTP_FORWARDED_FOR')?:
getenv('HTTP_FORWARDED')?:
getenv('REMOTE_ADDR');

【讨论】:

  • 这对我有用,因为标记为正确答案的那个没有。
  • getenv 如果未设置变量,则返回 false,如果未设置变量,$_SERVER 将出现“未定义索引”错误。
  • 我通常不喜欢嵌套三元组,但在这种情况下我真的很喜欢......
  • 我倾向于在 PHP 中完全避免三元组,因为它的(不合逻辑的)左关联性。见phpsadness.com/sad/30
  • GeriBoss,找出 phpsadness 测试用例的解决方案并同时使代码更具可读性并不难: echo (FALSE ? "a" : (FALSE ? "b" : "c"))."\n";回声(假?“a”:(真?“b”:“c”))。“\n”;回声(真?“a”:(假?“b”:“c”))。“\n”; echo (TRUE ? "a" : (TRUE ? "b" : "c"))."\n";
【解决方案3】:
    $ipaddress = '';
    if ($_SERVER['HTTP_CLIENT_IP'] != '127.0.0.1')
        $ipaddress = $_SERVER['HTTP_CLIENT_IP'];
    else if ($_SERVER['HTTP_X_FORWARDED_FOR'] != '127.0.0.1')
        $ipaddress = $_SERVER['HTTP_X_FORWARDED_FOR'];
    else if ($_SERVER['HTTP_X_FORWARDED'] != '127.0.0.1')
        $ipaddress = $_SERVER['HTTP_X_FORWARDED'];
    else if ($_SERVER['HTTP_FORWARDED_FOR'] != '127.0.0.1')
        $ipaddress = $_SERVER['HTTP_FORWARDED_FOR'];
    else if ($_SERVER['HTTP_FORWARDED'] != '127.0.0.1')
        $ipaddress = $_SERVER['HTTP_FORWARDED'];
    else if ($_SERVER['REMOTE_ADDR'] != '127.0.0.1')
        $ipaddress = $_SERVER['REMOTE_ADDR'];
    else
        $ipaddress = 'UNKNOWN';

【讨论】:

    【解决方案4】:

    这是一个使用本地和 LAN IP 地址过滤器获取 IP 地址的函数:

    function get_IP_address()
    {
        foreach (array('HTTP_CLIENT_IP',
                       'HTTP_X_FORWARDED_FOR',
                       'HTTP_X_FORWARDED',
                       'HTTP_X_CLUSTER_CLIENT_IP',
                       'HTTP_FORWARDED_FOR',
                       'HTTP_FORWARDED',
                       'REMOTE_ADDR') as $key){
            if (array_key_exists($key, $_SERVER) === true){
                foreach (explode(',', $_SERVER[$key]) as $IPaddress){
                    $IPaddress = trim($IPaddress); // Just to be safe
    
                    if (filter_var($IPaddress,
                                   FILTER_VALIDATE_IP,
                                   FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)
                        !== false) {
    
                        return $IPaddress;
                    }
                }
            }
        }
    }
    

    【讨论】:

    • code function getLocalIP(){ exec("ipconfig /all", $output); foreach($output as $line){ if (preg_match("/(.*)IPv4 地址(.*)/", $line)){ $ip = $line; $ip = str_replace("IPv4 地址...... $ip = str_replace("(首选)","",$ip); } } 返回修剪($ip); }
    • 这么多否定标志,但只有这个答案包含 FILTER_VALIDATE_IP,如果不过滤,这可能是一个主要的安全问题。
    【解决方案5】:

    它也适用于内部 IP 地址:

     function get_client_ip()
     {
          $ipaddress = '';
          if (getenv('HTTP_CLIENT_IP'))
              $ipaddress = getenv('HTTP_CLIENT_IP');
          else if(getenv('HTTP_X_FORWARDED_FOR'))
              $ipaddress = getenv('HTTP_X_FORWARDED_FOR');
          else if(getenv('HTTP_X_FORWARDED'))
              $ipaddress = getenv('HTTP_X_FORWARDED');
          else if(getenv('HTTP_FORWARDED_FOR'))
              $ipaddress = getenv('HTTP_FORWARDED_FOR');
          else if(getenv('HTTP_FORWARDED'))
              $ipaddress = getenv('HTTP_FORWARDED');
          else if(getenv('REMOTE_ADDR'))
              $ipaddress = getenv('REMOTE_ADDR');
          else
              $ipaddress = 'UNKNOWN';
    
          return $ipaddress;
     }
    

    【讨论】:

    • Sivanesh Govindan 答案的 100% 副本
    • return ($ip=getenv('HTTP_CLIENT_IP' ))?$ip:( ($ip=getenv('HTTP_X_FORWARDED_FOR' ))?$ip:( ($ip=getenv('HTTP_X_FORWARDED' ))?$ip:( ($ip=getenv('HTTP_FORWARDED_FOR' ))?$ip:( ($ip=getenv('HTTP_FORWARDED' ))?$ip:( ($ip=getenv('REMOTE_ADDR' )) ?$ip:false )))));
    猜你喜欢
    • 2013-07-07
    • 2012-12-05
    • 1970-01-01
    • 2019-01-14
    • 1970-01-01
    • 2018-07-27
    • 2016-03-27
    • 2011-05-26
    • 2019-11-13
    相关资源
    最近更新 更多