在写东西时碰到有需要取得用户真实ip地址的需求,但是最简单的$IP = $_SERVER["REMOTE_ADDR"]只适用于没有使用用户代理而直接访问的情况,其他情况得到的都是空地址或unknown(在PHP 中使用 [“REMOTE_ADDR”] 来取得客户端的 IP 地址,但如果客户端是使用代理服务器来访问,如果要获取真正的ip就需要使用[‘HTTP_X_FORWARDED_FOR’]),所以我们需要使用其他方法来取得用户的真实ip,从其他地方找了几种方法,亲测有效(高匿名代理这种情况暂时不予考虑),这里先贴一下代码:
1.
function getIp() {
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)) {
foreach (explode(',', $_SERVER[$key]) as $ip) {
$ip = trim($ip);
//会过滤掉保留地址和私有地址段的IP,例如 127.0.0.1会被过滤
//也可以修改成正则验证IP
if ((bool) filter_var($ip, FILTER_VALIDATE_IP,
FILTER_FLAG_IPV4 |
FILTER_FLAG_NO_PRIV_RANGE |
FILTER_FLAG_NO_RES_RANGE)) {
return $ip;
}
}
}
}
return null;
}
$real_IP = getIp();
var_dump($real_IP);
2.
function get_real_ip(){
static $realip;
if(isset($_SERVER)){
if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])){
$realip=$_SERVER['HTTP_X_FORWARDED_FOR'];
}else if(isset($_SERVER['HTTP_CLIENT_IP'])){
$realip=$_SERVER['HTTP_CLIENT_IP'];
}else{
$realip=$_SERVER['REMOTE_ADDR'];
}
}else{
// 但是当Web服务器API是ASAPI (IIS)的时候,getenv函数是不起作用的。这种情况下你如果用getenv来取得用户客户端ip的话,得到的将是错误的ip地址
if(getenv('HTTP_X_FORWARDED_FOR')){
$realip=getenv('HTTP_X_FORWARDED_FOR');
}else if(getenv('HTTP_CLIENT_IP')){
$realip=getenv('HTTP_CLIENT_IP');
}else{
$realip=getenv('REMOTE_ADDR');
}
}
return $realip;
}
$real_IP_2 = get_real_ip();
var_dump($real_IP_2);
3.
// 获取IP地址(摘自discuz)
function getIp_2(){
$ip='未知IP';
if(!empty($_SERVER['HTTP_CLIENT_IP'])){
return is_ip($_SERVER['HTTP_CLIENT_IP'])?$_SERVER['HTTP_CLIENT_IP']:$ip;
}elseif(!empty($_SERVER['HTTP_X_FORWARDED_FOR'])){
return is_ip($_SERVER['HTTP_X_FORWARDED_FOR'])?$_SERVER['HTTP_X_FORWARDED_FOR']:$ip;
}else{
return is_ip($_SERVER['REMOTE_ADDR'])?$_SERVER['REMOTE_ADDR']:$ip;
}
}
function is_ip($str){
$ip=explode('.',$str);
for($i=0;$i<count($ip);$i++){
if($ip[$i]>255){
return false;
}
}
return preg_match('/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/',$str);
}
$real_IP_3 = getIp_2();
var_dump($real_IP_3);
总结:
仔细观察一下,获取用户真实ip也就在以REMOTE_ADDR、HTTP_CLIENT_IP、HTTP_X_FORWARDED_FOR等几个变量之中兜兜转转,用户使用不同类型的代理或者使用代理时得到的这些变量是不一样的,具体可以参考一下其他朋友的文章如: