获取用户的真实IP
提取一个客户端请求的IP:
1. REMOTE_ADDR: 访问端(有可能是用户,有可能是代理的)IP;是你的客户端跟你的服务器“握手”时候的IP,离服务器最近的IP。
2. HTTP_X_FORWARDED_FOR: 浏览当前页面的用户计算机的网关,是从客户端到 REMOTE_ADDR 前一个 IP。
没有使用代理时,没有值。使用一层代理时,也就是客户端 IP。使用二层代理时,也就是“客户端IP,1层代理IP”,也就是相当于 IP
路径,中间用逗号隔开,注意不包括二层代理。使用三层代理时,也就是“客户端IP,1层代理IP,2层代理”,也就是相当于 IP
路径,中间用逗号隔开,注意不包括三层代理。
3. HTTP_CLIENT_IP: 客户端ip,是代理服务器发送的HTTP头。
在PHP 中使用 $_SERVER["REMOTE_ADDR"] 来取得客户端的 IP
地址,但如果客户端是使用代理服务器来访问,那取到的就是代理服务器的 IP 地址,而不是真正的客户端 IP
地址。要想透过代理服务器取得客户端的真实 IP 地址,就要使用 $_SERVER["HTTP_X_FORWARDED_FOR"] 来读取。
不过要注意的事,并不是每个代理服务器都能用 $_SERVER["HTTP_X_FORWARDED_FOR"] 来读取客户端的真实 IP,有些用此方法读取到的仍然是代理服务器的 IP。
还有一点需要注意的是:如果客户端没有通过代理服务器来访问,那么用$_SERVER["HTTP_X_FORWARDED_FOR"] 取到的值将是空的。
if ($_SERVER['HTTP_X_FORWARDED_FOR'] &&
preg_match(‘/^([0-9]{1,3}\.){3}[0-9]{1,3}$/’,$_SERVER['HTTP_X_FORWARDED_FOR']))
{
$onlineip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} elseif ($_SERVER['HTTP_CLIENT_IP'] && preg_match(‘/^([0-9]{1,3}\.){3}[0-9]{1,3}$/’,$_SERVER['HTTP_CLIENT_IP'])) {
$onlineip = $_SERVER['HTTP_CLIENT_IP'];
}
以下是ecshop的lib_base.php获取客户端真实ip的函数(real_ip),有许多情况的判断,主要判断客户端是否使用代理的情况,注意判断顺序,先判断客户端是否使用代理HTTP_X_FORWARDED_FOR
1 /** 2 * 获得用户的真实IP地址 3 * 4 * @access public 5 * @return string 6 */ 7 function real_ip() 8 { 9 static $realip = NULL; 10 11 if ($realip !== NULL) 12 { 13 return $realip; 14 } 15 16 if (isset($_SERVER)) 17 { 18 if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) 19 { 20 $arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']); 21 22 /* 取X-Forwarded-For中第一个非unknown的有效IP字符串 */ 23 foreach ($arr AS $ip) 24 { 25 $ip = trim($ip); 26 27 if ($ip != 'unknown') 28 { 29 $realip = $ip; 30 31 break; 32 } 33 } 34 } 35 elseif (isset($_SERVER['HTTP_CLIENT_IP'])) 36 { 37 $realip = $_SERVER['HTTP_CLIENT_IP']; 38 } 39 else 40 { 41 if (isset($_SERVER['REMOTE_ADDR'])) 42 { 43 $realip = $_SERVER['REMOTE_ADDR']; 44 } 45 else 46 { 47 $realip = '0.0.0.0'; 48 } 49 } 50 } 51 else 52 { 53 if (getenv('HTTP_X_FORWARDED_FOR')) 54 { 55 $realip = getenv('HTTP_X_FORWARDED_FOR'); 56 } 57 elseif (getenv('HTTP_CLIENT_IP')) 58 { 59 $realip = getenv('HTTP_CLIENT_IP'); 60 } 61 else 62 { 63 $realip = getenv('REMOTE_ADDR'); 64 } 65 } 66 67 preg_match("/[\d\.]{7,15}/", $realip, $onlineip); 68 $realip = !empty($onlineip[0]) ? $onlineip[0] : '0.0.0.0'; 69 70 return $realip; 71 }
再贴一段代码:
1 if(getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'), 'unknown')) { 2 $onlineip = getenv('HTTP_CLIENT_IP'); 3 } elseif(getenv('HTTP_X_FORWARDED_FOR') && strcasecmp(getenv('HTTP_X_FORWARDED_FOR'), 'unknown')) { 4 $onlineip = getenv('HTTP_X_FORWARDED_FOR'); 5 } elseif(getenv('REMOTE_ADDR') && strcasecmp(getenv('REMOTE_ADDR'), 'unknown')) { 6 $onlineip = getenv('REMOTE_ADDR'); 7 } elseif(isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown')) { 8 $onlineip = $_SERVER['REMOTE_ADDR']; 9 } 10 preg_match("/[\d\.]{7,15}/", $onlineip, $onlineipmatches); 11 $real_ip = $onlineipmatches[0] ? $onlineipmatches[0] : 'unknown';