获取对方真实IP程序之二
获取对方真实IP程序之二
还要有一个处理 HTTP_X_FORWARDED_FOR(如果有值的话)的函数:
function explode_and_foreach_them($forwarded_ips){
$arr = explode(',', $forwarded_ips);
if(0<count($arr)){
foreach ($arr as $ip){
$ip = trim($ip);
if ($ip != 'unknown'){
$realip = $realip.'+'.$ip;
break;
}
}
return $realip;
}else{
return $forwarded_ips;
}
}
返回真实的客户端IP:
function get_real_client_ip(){
if (!emptyempty($_SERVER['HTTP_CLIENT_IP']) && validate_ip($_SERVER['HTTP_CLIENT_IP'])) {
return $_SERVER['HTTP_CLIENT_IP'];
}
if (!emptyempty($_SERVER['HTTP_X_FORWARDED_FOR']) && validate_ipSERVER['HTTP_X_FORWARDED_FOR'])) {
return explode_and_foreach_them($_SERVER['HTTP_X_FORWARDED_FOR']);
}
if (!emptyempty($_SERVER['HTTP_X_FORWARDED']) && validate_ip($_SERVER['HTTP_X_FORWARDED'])) {
return $_SERVER['HTTP_X_FORWARDED'];
}
if (!emptyempty($_SERVER['HTTP_X_CLUSTER_CLIENT_IP']) && validate_ip($_SERVER['HTTP_X_CLUSTER_CLIENT_IP'])) {
return $_SERVER['HTTP_X_CLUSTER_CLIENT_IP'];
}
if (!emptyempty($_SERVER['HTTP_FORWARDED_FOR']) && validate_ip($_SERVER['HTTP_FORWARDED_FOR'])) {
return explode_and_foreach_them($_SERVER['HTTP_FORWARDED_FOR']);
}
if (!emptyempty($_SERVER['HTTP_FORWARDED']) && validate_ip($_SERVER['HTTP_FORWARDED'])) {
return $_SERVER['HTTP_FORWARDED'];
}
return $_SERVER['REMOTE_ADDR'];
}
上面的函数调用了上上面的函数,所以,它们是要一起用的。下面的液压隔膜计量泵函数有多个return,而不是赋值给一个变量,然后返回变量,这叫Guard Clauses(后卫条款?):权威的维基百科没有收录这个词,不过倒是在Wiki概念创建者的液压隔膜计量泵网站找到了记录http://c2.com/cgi/wiki?GuardClause还有另外一个高人的描述:http://www.refactoring.com/catalog/replaceNestedConditionalWithGuardClauses.html据信,这个词最早出现在出版于1996年10月13日(上述Wiki网站标注为1997年出版,显然是错的)的一本由 KentBeck 与 Prentice Hall合写的书《Smalltalk Best Practice Patterns》(ISBN-10: : 0-13-476904-X | ISBN-13: 978-0134769042),感兴趣的淫可以找来览一览,有好事者已经在2011年将该书的一部分(仅有几百KB,应该是2-4MB才对的)的PDF格式上传至新浪爱问。
下面的函数来自于国内的某个shop的源码:
function get_real_client_ip(){
static $realip = NULL;
if ($realip !== NULL){ return $realip; }
if (isset($_SERVER)){
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])){
$realip = explode_and_foreach_them($_SERVER['HTTP_X_FORWARDED_FOR']);
}elseif (isset($_SERVER['HTTP_CLIENT_IP'])){
$realip = $_SERVER['HTTP_CLIENT_IP'];
}else{
if (isset($_SERVER['REMOTE_ADDR'])){
$realip = $_SERVER['REMOTE_ADDR'];
}else{
$realip = '0.0.0.0';
}
}
}else{
//getenv(string varname)获取环境变量的PHP函数,它与服务器超级全局变量数组$_SERVER的区别是:getenv()不支持IIS的isapi方式运行的php
//putenv(string varname)设置环境变量的PHP函数
if (getenv('HTTP_X_FORWARDED_FOR')){
$realip = getenv('HTTP_X_FORWARDED_FOR');
}elseif (getenv('HTTP_CLIENT_IP')){
$realip = getenv('HTTP_CLIENT_IP');
}else{
$realip = getenv('REMOTE_ADDR');
}
}
preg_match("/[\d\.]{7,15}/", $realip, $onlineip);
$realip = !emptyempty($onlineip[0]) ? $onlineip[0] : '0.0.0.0';
return $realip;
}
精简一下上面的函数:
function get_client_ip()
{
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); http://www.huainan.gov.cn/
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;
}