快捷搜索:   nginx

PHP获取用户代理IP后面真实IP的方法 PHP获取访客IP的方法

我们在网站建设中都希望能记录到访客的真实IP,但是现在网上的代理太多了,各种高匿名,匿名,透明的满天飞,因此这里也只是提供一个不是很完美的解决方案,目前在网上搜索了一大圈,没有真正能有效的对抗高匿名代理获取到真实IP的方法,如果您有,可以留言告诉我们。
先看下面这段,笨牛网在使用的代码:

<?php
function get_real_ip(){
if(getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'), 'unknown'))
{$ip = getenv('HTTP_CLIENT_IP');}
elseif(getenv('HTTP_X_FORWARDED_FOR') && strcasecmp(getenv('HTTP_X_FORWARDED_FOR'), 'unknown'))
{$ip = getenv('HTTP_X_FORWARDED_FOR');}
elseif(getenv('REMOTE_ADDR') && strcasecmp(getenv('REMOTE_ADDR'), 'unknown'))
{$ip = getenv('REMOTE_ADDR');}
elseif(isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown'))
{$ip = $_SERVER['REMOTE_ADDR'];}
return preg_match("/[\d\.]{7,15}/", $ip, $matches) ? $matches[0] : false;
}
function ipdata($ip,$name="0")
{
$url="http://ip.taobao.com/service/getIpInfo.php?ip=";
$data=json_decode(file_get_contents($url.$ip)); $ipdata=$data->data;
if($name=="all")   {return $ipdata;}
else if($name=="0"){return $ipdata->country.$ipdata->region.$ipdata->city.$ipdata->isp;}
else if($name=="1"){return $ipdata->country;}
else if($name=="2"){return $ipdata->area;}
else if($name=="3"){return $ipdata->region;}
else if($name=="4"){return $ipdata->city;}
else if($name=="5"){return $ipdata->county;}
else if($name=="6"){return $ipdata->isp;}
}
$ipzhenshi = get_real_ip();
$ipdaili = $_SERVER['REMOTE_ADDR'];
if($_SERVER['HTTP_X_FORWARDED_FOR'])
{
echo "您的代理IP是[<a href='".$weblink.$ipdaili."'><font color=#FF0000>".$ipdaili."</font></a>]&nbsp;&nbsp;来自".ipdata($ipdaili)."";
echo "您的真实IP是[<a href='".$weblink.$ipzhenshi."'><font color=#FF0000>".$ipzhenshi."</font></a>]&nbsp;&nbsp;来自".ipdata($ipzhenshi)."";
}
else{
  echo "您的IP是[<a href='".$weblink.$ipdaili."'><font color=#FF0000>".$ipzhenshi."</font></a>]&nbsp;&nbsp;来自".ipdata($ipzhenshi)."";}
?>




这里定义了两个function,第一个是获取真实IP用,第二个是调用淘宝的接口获得IP的归属地;

这里用到的$_SERVER是服务器超级全局变量数组,用$_SERVER['REMOTE_ADDR']可以获取到客户端的IP地址.二者的区别在于,getenv不支持IIS的isapi方式运行的php.

strcasecmp(string1,string2)字符串函数的用法是把string1和string2进行比较,如果相等返回0,如果string1大于string2,返回大于0的数,小于则返回小于0的数.

函数先使用客户IP,如果不成立尝试用代理的方法,如果不行,再使用REMOTE_ADDR.

考虑到IP的欺骗,和多重代理改动了下面这个多重代理检测的代码.

function getip() {
      $unknown = 'unknown';
      if ( isset($_SERVER['HTTP_X_FORWARDED_FOR']) && $_SERVER['HTTP_X_FORWARDED_FOR'] && strcasecmp($_SERVER['HTTP_X_FORWARDED_FOR'], $unknown) ) {
      $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
        } elseif ( isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], $unknown) ) {
      $ip = $_SERVER['REMOTE_ADDR'];
}
/*
处理多层代理的情况
或者使用正则方式:$ip = preg_match("/[\d\.]{7,15}/", $ip, $matches) ? $matches[0] : $unknown;
*/
if (false !== strpos($ip, ','))
     $ip = reset(explode(',', $ip));
     return $ip;
}


一、没有使用代理服务器的PHP获取客户端IP情况:

REMOTE_ADDR = 客户端IP
HTTP_X_FORWARDED_FOR = 没数值或不显示

二、使用透明代理服务器的情况:Transparent Proxies

REMOTE_ADDR = 最后一个代理服务器 IP

顶(1)
踩(0)

您可能还会对下面的文章感兴趣:

最新评论