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>] 来自".ipdata($ipdaili).""; echo "您的真实IP是[<a href='".$weblink.$ipzhenshi."'><font color=#FF0000>".$ipzhenshi."</font></a>] 来自".ipdata($ipzhenshi).""; } else{ echo "您的IP是[<a href='".$weblink.$ipdaili."'><font color=#FF0000>".$ipzhenshi."</font></a>] 来自".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
- 最新评论