关于环境变量:如何在PHP中获取客户端IP地址

How to get the client IP address in PHP

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

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


无论您做什么,请确保不要信任从客户机发送的数据。$_SERVER['REMOTE_ADDR']包含连接方的真实IP地址。这是你能找到的最可靠的价值。

但是,它们可能位于代理服务器之后,在这种情况下,代理可能设置了$_SERVER['HTTP_X_FORWARDED_FOR'],但这个值很容易被欺骗。例如,它可以由没有代理的人设置,或者IP可以是代理后面LAN的内部IP。

这意味着,如果要保存$_SERVER['HTTP_X_FORWARDED_FOR'],请确保还保存$_SERVER['REMOTE_ADDR']值。例如,通过在数据库的不同字段中保存这两个值。

如果要将IP以字符串形式保存到数据库中,请确保至少有45个字符的空间。IPv6将保留下来,并且这些地址大于旧的IPv4地址。

(请注意,ipv6最多使用39个字符,但也有一个针对ipv4地址的特殊ipv6表示法,其完整形式最多可以使用45个字符。所以,如果你知道你在做什么,你可以用39个字符,但如果你只是想设置并忘记它,用45个字符)。


$_SERVER['REMOTE_ADDR']实际上可能不包含真正的客户机IP地址,因为它将为通过代理连接的客户机提供代理地址,例如。那可能不过,那就做你真正想要的吧,这取决于你对ips做了什么。如果你想知道你的流量来自何处,或者记住用户最后一次连接的IP,而代理或NAT网关的公共IP可能更适合存储,那么某人的私有RFC1918地址可能对你没有任何好处。

有几个HTTP头,如X-Forwarded-For,可以由各种代理设置,也可以不由各种代理设置。问题是这些只是任何人都可以设置的HTTP头。他们的内容没有保证。$_SERVER['REMOTE_ADDR']是Web服务器从中接收连接并将响应发送到的实际物理IP地址。任何其他信息都是随意的和自愿的。只有一种情况下您可以信任此信息:您正在控制设置此头的代理。这意味着,只有当你100%知道标题的位置和设置方式时,你才应该注意它的重要性。

说到这里,下面是一些示例代码:

1
2
3
4
5
6
7
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
    $ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
    $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
    $ip = $_SERVER['REMOTE_ADDR'];
}

编者按:使用上面的代码会带来安全隐患。客户机可以将所有HTTP头信息(即$_SERVER['HTTP_...设置为它想要的任意值。因此,使用$_SERVER['REMOTE_ADDR']更可靠,因为用户无法设置它。

发件人:http://roshanbh.com.np/2007/12/getting-real-ip-address-in-php.html


1
echo $_SERVER['REMOTE_ADDR'];

http://php.net/manual/en/reserved.variables.server.php


下面是一个更清晰的代码示例,它是获取用户IP地址的好方法。

1
$ip = $_SERVER['HTTP_CLIENT_IP'] ? $_SERVER['HTTP_CLIENT_IP'] : ($_SERVER['HTTP_X_FORWARDED_FOR'] ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR']);

下面是使用ELVIS运算符的较短版本:

1
$_SERVER['HTTP_CLIENT_IP'] ? : ($_SERVER['HTTP_X_FORWARDED_FOR'] ? : $_SERVER['REMOTE_ADDR']);

下面是一个使用ISSET删除通知的版本(谢谢,@shasi kanth):

1
$ip = isset($_SERVER['HTTP_CLIENT_IP']) ? $_SERVER['HTTP_CLIENT_IP'] : isset($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR'];


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


我最喜欢的解决方案是Zend Framework 2的使用方式。它还考虑了$_SERVER属性HTTP_X_FORWARDED_FORHTTP_CLIENT_IPREMOTE_ADDR,但它声明了一个类,以便它设置一些受信任的代理,并返回一个IP地址而不是一个数组。我认为这是最接近它的解决方案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
class RemoteAddress
{
    /**
     * Whether to use proxy addresses or not.
     *
     * As default this setting is disabled - IP address is mostly needed to increase
     * security. HTTP_* are not reliable since can easily be spoofed. It can be enabled
     * just for more flexibility, but if user uses proxy to connect to trusted services
     * it's his/her own risk, only reliable field for IP address is $_SERVER['REMOTE_ADDR'].
     *
     * @var bool
     */

    protected $useProxy = false;

    /**
     * List of trusted proxy IP addresses
     *
     * @var array
     */

    protected $trustedProxies = array();

    /**
     * HTTP header to introspect for proxies
     *
     * @var string
     */

    protected $proxyHeader = 'HTTP_X_FORWARDED_FOR';

    // [...]

    /**
     * Returns client IP address.
     *
     * @return string IP address.
     */

    public function getIpAddress()
    {
        $ip = $this->getIpAddressFromProxy();
        if ($ip) {
            return $ip;
        }

        // direct IP address
        if (isset($_SERVER['REMOTE_ADDR'])) {
            return $_SERVER['REMOTE_ADDR'];
        }

        return '';
    }

    /**
     * Attempt to get the IP address for a proxied client
     *
     * @see http://tools.ietf.org/html/draft-ietf-appsawg-http-forwarded-10#section-5.2
     * @return false|string
     */

    protected function getIpAddressFromProxy()
    {
        if (!$this->useProxy
            || (isset($_SERVER['REMOTE_ADDR']) && !in_array($_SERVER['REMOTE_ADDR'], $this->trustedProxies))
        ) {
            return false;
        }

        $header = $this->proxyHeader;
        if (!isset($_SERVER[$header]) || empty($_SERVER[$header])) {
            return false;
        }

        // Extract IPs
        $ips = explode(',', $_SERVER[$header]);
        // trim, so we can compare against trusted proxies properly
        $ips = array_map('trim', $ips);
        // remove trusted proxy IPs
        $ips = array_diff($ips, $this->trustedProxies);

        // Any left?
        if (empty($ips)) {
            return false;
        }

        // Since we've removed any known, trusted proxy servers, the right-most
        // address represents the first IP we do not know about -- i.e., we do
        // not know if it is a proxy server, or a client. As such, we treat it
        // as the originating IP.
        // @see http://en.wikipedia.org/wiki/X-Forwarded-For
        $ip = array_pop($ips);
        return $ip;
    }

    // [...]
}

请参阅以下完整代码:https://raw.githubusercontent.com/zendframework/zend-http/master/src/phpenvironment/remoteaddress.php


Internet背后有不同类型的用户,因此我们希望从不同的部分捕获IP地址。那些是:

1。$_SERVER['REMOTE_ADDR']这包含客户端的真实IP地址。这是您可以从用户那里找到的最可靠的值。

2。埃多克斯1〔10〕。-这将获取用户查看当前页面的主机名。但要使该脚本工作,必须配置httpd.conf内部的主机名查找。

三。江户十一〔11〕号-这将在用户来自共享Internet服务时获取IP地址。

4。$_SERVER['HTTP_X_FORWARDED_FOR']—当用户在代理之后时,它将从用户那里获取IP地址。

因此,我们可以使用下面的组合函数从不同位置查看的用户那里获取真实的IP地址,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// Function to get the user IP address
function getUserIP() {
    $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_X_CLUSTER_CLIENT_IP']))
        $ipaddress = $_SERVER['HTTP_X_CLUSTER_CLIENT_IP'];
    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;
}


下面是我发现的最先进的方法,我过去已经尝试过其他一些方法。确保获取访问者的IP地址是有效的(但请注意,任何黑客都可以轻易地伪造IP地址)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
function get_ip_address() {

    // Check for shared Internet/ISP IP
    if (!empty($_SERVER['HTTP_CLIENT_IP']) && validate_ip($_SERVER['HTTP_CLIENT_IP'])) {
        return $_SERVER['HTTP_CLIENT_IP'];
    }

    // Check for IP addresses passing through proxies
    if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {

        // Check if multiple IP addresses exist in var
        if (strpos($_SERVER['HTTP_X_FORWARDED_FOR'], ',') !== false) {
            $iplist = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
            foreach ($iplist as $ip) {
                if (validate_ip($ip))
                    return $ip;
            }
        }
        else {
            if (validate_ip($_SERVER['HTTP_X_FORWARDED_FOR']))
                return $_SERVER['HTTP_X_FORWARDED_FOR'];
        }
    }
    if (!empty($_SERVER['HTTP_X_FORWARDED']) && validate_ip($_SERVER['HTTP_X_FORWARDED']))
        return $_SERVER['HTTP_X_FORWARDED'];
    if (!empty($_SERVER['HTTP_X_CLUSTER_CLIENT_IP']) && validate_ip($_SERVER['HTTP_X_CLUSTER_CLIENT_IP']))
        return $_SERVER['HTTP_X_CLUSTER_CLIENT_IP'];
    if (!empty($_SERVER['HTTP_FORWARDED_FOR']) && validate_ip($_SERVER['HTTP_FORWARDED_FOR']))
        return $_SERVER['HTTP_FORWARDED_FOR'];
    if (!empty($_SERVER['HTTP_FORWARDED']) && validate_ip($_SERVER['HTTP_FORWARDED']))
        return $_SERVER['HTTP_FORWARDED'];

    // Return unreliable IP address since all else failed
    return $_SERVER['REMOTE_ADDR'];
}

/**
 * Ensures an IP address is both a valid IP address and does not fall within
 * a private network range.
 */

function validate_ip($ip) {

    if (strtolower($ip) === 'unknown')
        return false;

    // Generate IPv4 network address
    $ip = ip2long($ip);

    // If the IP address is set and not equivalent to 255.255.255.255
    if ($ip !== false && $ip !== -1) {
        // Make sure to get unsigned long representation of IP address
        // due to discrepancies between 32 and 64 bit OSes and
        // signed numbers (ints default to signed in PHP)
        $ip = sprintf('%u', $ip);

        // Do private network range checking
        if ($ip >= 0 && $ip <= 50331647)
            return false;
        if ($ip >= 167772160 && $ip <= 184549375)
            return false;
        if ($ip >= 2130706432 && $ip <= 2147483647)
            return false;
        if ($ip >= 2851995648 && $ip <= 2852061183)
            return false;
        if ($ip >= 2886729728 && $ip <= 2887778303)
            return false;
        if ($ip >= 3221225984 && $ip <= 3221226239)
            return false;
        if ($ip >= 3232235520 && $ip <= 3232301055)
            return false;
        if ($ip >= 4294967040)
            return false;
    }
    return true;
}


答案是使用$_SERVER变量。例如,$_SERVER["REMOTE_ADDR"]将返回客户机的IP地址。


正如所有其他人之前所说,您可以使用$_SERVER['REMOTE_ADDR'];获取客户机IP地址。

此外,如果您需要有关用户的更多信息,可以使用:

1
2
3
4
5
6
<?php
    $ip = '0.0.0.0';
    $ip = $_SERVER['REMOTE_ADDR'];
    $clientDetails = json_decode(file_get_contents("http://ipinfo.io/$ip/json"));
    echo"You're logged in from:" . $clientDetails->country ."";
?>

客户的更具体信息在$clientdetails中。< BR>您可以通过以下方式获取存储在$clientdetails变量中的json项:$clientdetails->postalcode/hostname/region/loc…

我用ipinfo.io获取额外信息。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$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;


这是我使用的方法,它验证IPv4输入:

1
2
3
4
5
6
7
8
9
10
11
// Get user IP address
if ( isset($_SERVER['HTTP_CLIENT_IP']) && ! empty($_SERVER['HTTP_CLIENT_IP'])) {
    $ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif ( isset($_SERVER['HTTP_X_FORWARDED_FOR']) && ! empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
    $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
    $ip = (isset($_SERVER['REMOTE_ADDR'])) ? $_SERVER['REMOTE_ADDR'] : '0.0.0.0';
}

$ip = filter_var($ip, FILTER_VALIDATE_IP);
$ip = ($ip === false) ? '0.0.0.0' : $ip;


我喜欢这个代码段:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function getClientIP() {

    if (isset($_SERVER)) {

        if (isset($_SERVER["HTTP_X_FORWARDED_FOR"]))
            return $_SERVER["HTTP_X_FORWARDED_FOR"];

        if (isset($_SERVER["HTTP_CLIENT_IP"]))
            return $_SERVER["HTTP_CLIENT_IP"];

        return $_SERVER["REMOTE_ADDR"];
    }

    if (getenv('HTTP_X_FORWARDED_FOR'))
        return getenv('HTTP_X_FORWARDED_FOR');

    if (getenv('HTTP_CLIENT_IP'))
        return getenv('HTTP_CLIENT_IP');

    return getenv('REMOTE_ADDR');
}


试试这个:

1
 $_SERVER['REMOTE_ADDR'];


好吧,这可以通过使用名为$_SERVERGLOBAL变量来实现。

$_SERVER是一个具有属性名REMOTE_ADDR的数组。

只需这样分配:

1
$userIp = $_SERVER['REMOTE_ADDR'];

或直接使用,如echo $_SERVER['REMOTE_ADDR'];。或echo ($_SERVER['REMOTE_ADDR']);


以下函数确定所有可能性,并以逗号分隔格式(IP、IP等)返回值。

它还有一个可选的验证函数作为(默认情况下禁用的第一个参数),用于根据(专用范围和保留范围)验证IP地址。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<?php
echo GetClientIP(true);

function GetClientIP($validate = False) {
  $ipkeys = array(
  'REMOTE_ADDR',
  'HTTP_CLIENT_IP',
  'HTTP_X_FORWARDED_FOR',
  'HTTP_X_FORWARDED',
  'HTTP_FORWARDED_FOR',
  'HTTP_FORWARDED',
  'HTTP_X_CLUSTER_CLIENT_IP'
  );

  /*
  Now we check each key against $_SERVER if containing such value
  */

  $ip = array();
  foreach ($ipkeys as $keyword) {
    if (isset($_SERVER[$keyword])) {
      if ($validate) {
        if (ValidatePublicIP($_SERVER[$keyword])) {
          $ip[] = $_SERVER[$keyword];
        }
      }
      else{
        $ip[] = $_SERVER[$keyword];
      }
    }
  }

  $ip = ( empty($ip) ? 'Unknown' : implode(",", $ip) );
  return $ip;
}

function ValidatePublicIP($ip){
  if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
    return true;
  }
  else {
    return false;
  }
}

这个函数很紧凑,您可以在任何地方使用它。但是!

别忘了!在这种类型的函数或代码块中,不能保证记录用户的真实IP地址,因为有些用户可以使用代理或另一个安全网关使其不可见或无法跟踪

PHP功能:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function GetIP()
{
    if ( getenv("HTTP_CLIENT_IP") ) {
        $ip = getenv("HTTP_CLIENT_IP");
    } elseif ( getenv("HTTP_X_FORWARDED_FOR") ) {
        $ip = getenv("HTTP_X_FORWARDED_FOR");
        if ( strstr($ip, ',') ) {
            $tmp = explode(',', $ip);
            $ip = trim($tmp[0]);
        }
    } else {
        $ip = getenv("REMOTE_ADDR");
    }
    return $ip;
}

用途:

$IP = GetIP();或直接GetIP();


获取IP地址的安全和警告感知代码段:

1
2
3
4
$ip = filter_input(INPUT_SERVER, 'HTTP_CLIENT_IP', FILTER_VALIDATE_IP)
    ?: filter_input(INPUT_SERVER, 'HTTP_X_FORWARDED_FOR', FILTER_VALIDATE_IP)
    ?: $_SERVER['REMOTE_ADDR']
    ?? '0.0.0.0'; // Or other value fits"not defined" in your logic

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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;
}


下面是获取客户端IP地址的一行程序版本:

$ip = @$_SERVER['HTTP_CLIENT_IP'] ?: @$_SERVER['HTTP_X_FORWARDED_FOR'] ?: @$_SERVER['REMOTE_ADDR'];

笔记:

  • 通过使用@,它将抑制php通知。
  • HTTP_X_FORWARDED_FOR中的值可能包含多个用逗号分隔的地址,因此如果您希望获得第一个地址,可以使用以下方法:

    1
    current(explode(',', @$_SERVER['HTTP_X_FORWARDED_FOR']))

此函数应按预期工作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
function Get_User_Ip()
{
    $IP = false;
    if (getenv('HTTP_CLIENT_IP'))
    {
        $IP = getenv('HTTP_CLIENT_IP');
    }
    else if(getenv('HTTP_X_FORWARDED_FOR'))
    {
        $IP = getenv('HTTP_X_FORWARDED_FOR');
    }
    else if(getenv('HTTP_X_FORWARDED'))
    {
        $IP = getenv('HTTP_X_FORWARDED');
    }
    else if(getenv('HTTP_FORWARDED_FOR'))
    {
        $IP = getenv('HTTP_FORWARDED_FOR');
    }
    else if(getenv('HTTP_FORWARDED'))
    {
        $IP = getenv('HTTP_FORWARDED');
    }
    else if(getenv('REMOTE_ADDR'))
    {
        $IP = getenv('REMOTE_ADDR');
    }

    //If HTTP_X_FORWARDED_FOR == server ip
    if((($IP) && ($IP == getenv('SERVER_ADDR')) && (getenv('REMOTE_ADDR')) || (!filter_var($IP, FILTER_VALIDATE_IP))))
    {
        $IP = getenv('REMOTE_ADDR');
    }

    if($IP)
    {
        if(!filter_var($IP, FILTER_VALIDATE_IP))
        {
            $IP = false;
        }
    }
    else
    {
        $IP = false;
    }
    return $IP;
}

就在这一点上,我很惊讶它还没有被提到,是要得到正确的IP地址的那些网站是依附在像CloudFlare基础设施。它会破坏你的IP地址,并赋予它们相同的值。幸运的是,它们也有一些服务器头可用。不是我重写已经写的内容,而是在这里寻找一个更简洁的答案,是的,很久以前我也经历过这个过程。https://stackoverflow.com/a/14985633/1190051


像下面这样?

1
2
3
4
if (($ip=filter_input(INPUT_SERVER, 'REMOTE_ADDR', validate_ip)) === false or empty($ip)) {
    exit;
}
echo $ip;

聚苯乙烯

1
2
3
4
if (($ip=filter_input(INPUT_SERVER, 'REMOTE_ADDR', FILTER_VALIDATE_IP|FILTER_FLAG_NO_PRIV_RANGE|FILTER_FLAG_NO_RES_RANGE)) === false) {
    header('HTTP/1.0 400 Bad Request');
    exit;
}

所有以"http_uuu"或"x-"开头的头都可能被欺骗,分别由用户定义。如果你想跟踪,使用cookies等。


这是一个简单的一行

1
$ip = $_SERVER['HTTP_X_FORWARDED_FOR']?: $_SERVER['HTTP_CLIENT_IP']?: $_SERVER['REMOTE_ADDR'];

编辑:

上面的代码可能会返回保留的地址(如10.0.0.1)、路上所有代理服务器的地址列表等。要处理这些情况,请使用以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function valid_ip($ip) {
    // for list of reserved IP addresses, see https://en.wikipedia.org/wiki/Reserved_IP_addresses
    return $ip && substr($ip, 0, 4) != '127.' && substr($ip, 0, 4) != '127.' && substr($ip, 0, 3) != '10.' && substr($ip, 0, 2) != '0.' ? $ip : false;
}

function get_client_ip() {
    // using explode to get only client ip from list of forwarders. see https://en.wikipedia.org/wiki/X-Forwarded-For
    return
    @$_SERVER['HTTP_X_FORWARDED_FOR'] ? explode(',', $_SERVER['HTTP_X_FORWARDED_FOR'], 2)[0] :
    @$_SERVER['HTTP_CLIENT_IP'] ? explode(',', $_SERVER['HTTP_CLIENT_IP'], 2)[0] :
    valid_ip(@$_SERVER['REMOTE_ADDR']) ?:
    'UNKNOWN';
}

echo get_client_ip();


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// Function to get the client ip address
function get_ip()
{

if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
    $ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
    $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
    $ip = $_SERVER['REMOTE_ADDR'];
}
return $ip;


}

1
$_SERVER['REMOTE_ADDR'];

例子:

1
2
3
4
5
6
7
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
    $ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
    $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
    $ip = $_SERVER['REMOTE_ADDR'];
}