如何使用PHP获取客户端IP地址?
我想通过他/她的IP地址登录到我的网站的用户的记录。
如何使用PHP获取客户端IP地址?
我想通过他/她的IP地址登录到我的网站的用户的记录。
当前回答
你可以使用下面的函数
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;
}
其他回答
echo $_SERVER['REMOTE_ADDR'];
http://php.net/manual/en/reserved.variables.server.php
正如所有其他人所说,你可以使用$_SERVER['REMOTE_ADDR'];获取客户端IP地址。
另外,如果你需要一个用户的更多信息,你可以使用这个:
<?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: <b>" . $clientDetails->country . "</b>";
?>
客户端更具体的信息放在$clientDetails中。 $clientDetails->PostalCode/hostname/region/loc…
我用的是ipinfo。IO来获取额外的信息。
下面是一段代码,可以通过检查各种源来选择一个有效的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;
}
用于获取IP地址的安全和警告感知代码段:
$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
下面是一个很好的获取用户IP地址的干净代码示例。
$ip = $_SERVER['HTTP_CLIENT_IP']
? $_SERVER['HTTP_CLIENT_IP']
: ($_SERVER['HTTP_X_FORWARDED_FOR']
? $_SERVER['HTTP_X_FORWARDED_FOR']
: $_SERVER['REMOTE_ADDR']);
下面是一个使用elvis操作符的简短版本:
$_SERVER['HTTP_CLIENT_IP']
? : ($_SERVER['HTTP_X_FORWARDED_FOR']
? : $_SERVER['REMOTE_ADDR']);
下面是一个使用isset删除通知的版本(谢谢你,@shasi kanth):
$ip = isset($_SERVER['HTTP_CLIENT_IP'])
? $_SERVER['HTTP_CLIENT_IP']
: (isset($_SERVER['HTTP_X_FORWARDED_FOR'])
? $_SERVER['HTTP_X_FORWARDED_FOR']
: $_SERVER['REMOTE_ADDR']);