如何使用PHP获取客户端IP地址?

我想通过他/她的IP地址登录到我的网站的用户的记录。


当前回答

快速解决方案(无错误)

function getClientIP():string
{
    $keys=array('HTTP_CLIENT_IP','HTTP_X_FORWARDED_FOR','HTTP_X_FORWARDED','HTTP_FORWARDED_FOR','HTTP_FORWARDED','REMOTE_ADDR');
    foreach($keys as $k)
    {
        if (!empty($_SERVER[$k]) && filter_var($_SERVER[$k], FILTER_VALIDATE_IP))
        {
            return $_SERVER[$k];
        }
    }
    return "UNKNOWN";
}

其他回答

它应该包含在$_SERVER['REMOTE_ADDR']变量中。

如果您不喜欢使用If -else/switch语句,那么下面的解决方案适合您。

function get_client_ip()
{
    $fields = array(
        'HTTP_CF_CONNECTING_IP',
        'HTTP_X_SUCURI_CLIENTIP',
        'HTTP_CLIENT_IP',
        'HTTP_X_FORWARDED_FOR',
        'HTTP_X_FORWARDED',
        'HTTP_FORWARDED_FOR',
        'HTTP_FORWARDED',
        'REMOTE_ADDR',
        // more custom fields
    );

    foreach ($fields as $ip_field) {
        if (!empty($_SERVER[$ip_field])) {
            return $_SERVER[$ip_field];
        }
    }

    return null;
}
$ip = "";

if (!empty($_SERVER["HTTP_CLIENT_IP"]))
{
    // Check for IP address from shared Internet
    $ip = $_SERVER["HTTP_CLIENT_IP"];
}
elseif (!empty($_SERVER["HTTP_X_FORWARDED_FOR"]))
{
    // Check for the proxy user
    $ip = $_SERVER["HTTP_X_FORWARDED_FOR"];
}
else
{
    $ip = $_SERVER["REMOTE_ADDR"];
}
echo $ip;

下面是一段代码,可以通过检查各种源来选择一个有效的IP。

首先,它检查'REMOTE_ADDR'是否是一个公共IP(并且不是您信任的反向代理之一),然后遍历其中一个HTTP头,直到找到一个公共IP并返回它。(PHP 5.2 +)

只要反向代理是可信的,或者服务器与客户端直接连接,它就应该是可靠的。

//Get client's IP or null if nothing looks valid
function ip_get($allow_private = false)
{
  //Place your trusted proxy server IPs here.
  $proxy_ip = ['127.0.0.1'];

  //The header to look for (Make sure to pick the one that your trusted reverse proxy is sending or else you can get spoofed)
  $header = 'HTTP_X_FORWARDED_FOR'; //HTTP_CLIENT_IP, HTTP_X_FORWARDED, HTTP_FORWARDED_FOR, HTTP_FORWARDED

  //If 'REMOTE_ADDR' seems to be a valid client IP, use it.
  if(ip_check($_SERVER['REMOTE_ADDR'], $allow_private, $proxy_ip)) return $_SERVER['REMOTE_ADDR'];

  if(isset($_SERVER[$header]))
  {
    //Split comma separated values [1] in the header and traverse the proxy chain backwards.
    //[1] https://en.wikipedia.org/wiki/X-Forwarded-For#Format
    $chain = array_reverse(preg_split('/\s*,\s*/', $_SERVER[$header]));
    foreach($chain as $ip) if(ip_check($ip, $allow_private, $proxy_ip)) return $ip;
  }

   return null;
}

//Check for valid IP. If 'allow_private' flag is set to truthy, it allows private IP ranges as valid client IP as well. (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16)
//Pass your trusted reverse proxy IPs as $proxy_ip to exclude them from being valid.
function ip_check($ip, $allow_private = false, $proxy_ip = [])
{
  if(!is_string($ip) || is_array($proxy_ip) && in_array($ip, $proxy_ip)) return false;
  $filter_flag = FILTER_FLAG_NO_RES_RANGE;

  if(!$allow_private)
  {
    //Disallow loopback IP range which doesn't get filtered via 'FILTER_FLAG_NO_PRIV_RANGE' [1]
    //[1] https://www.php.net/manual/en/filter.filters.validate.php
    if(preg_match('/^127\.$/', $ip)) return false;
    $filter_flag |= FILTER_FLAG_NO_PRIV_RANGE;
  }

  return filter_var($ip, FILTER_VALIDATE_IP, $filter_flag) !== false;
}

你可以使用下面的函数

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;
}