在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"] 取到的值将是空的。因此,如果要在程序中使用此方法,可以这样处理:
<?php
if ($_SERVER["HTTP_X_FORWARDED_FOR"]=="")
{
$user_ip=$_SERVER["REMOTE_ADDR"];
}
else
$user_ip=$_SERVER["HTTP_X_FORWARDED_FOR"];
?>
即:如果客户端通过代理服务器,则取 HTTP_X_FORWARDED_FOR 的值,如果没通过代理服务器,就取 REMOTE_ADDR 的值。
获得客户端真实的IP地址
代码
function GetIP(){
if (getenv("HTTP_CLIENT_IP") && strcasecmp(getenv("HTTP_CLIENT_IP"),
"unknown"))
$ip = getenv("HTTP_CLIENT_IP");
else if (getenv("HTTP_X_FORWARDED_FOR") && strcasecmp(getenv
("HTTP_X_FORWARDED_FOR"), "unknown"))
$ip = getenv("HTTP_X_FORWARDED_FOR");
else if (getenv("REMOTE_ADDR") && strcasecmp(getenv("REMOTE_ADDR"),
"unknown"))
$ip = getenv("REMOTE_ADDR");
else if (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] &&
strcasecmp($_SERVER['REMOTE_ADDR'], "unknown"))
$ip = $_SERVER['REMOTE_ADDR'];
else
$ip = "unknown";
return($ip);
}
我的IP类
代码
<?php
/**
* @copyright Copyright (c) 2010 FANG.COM
*
* The base class of handling IP
*
* @author dusong
* @version v 0.1 2010-03-03
*/
class Ip {
/**
* 取IP
* @return string
*/
/**
*
*REMOTE_ADDR 是你的客户端跟你的服务器“握手”时候的IP。如果使用了“匿名代理”,REMOTE_ADDR将显示代理服务器的IP。 HTTP_CLIENT_IP 是代理服务器发送的HTTP头。如果是“超级匿名代理”
*,则返回none值。同样,REMOTE_ADDR也会被替换为这个代理服务器的IP。
*/
public static function get()
{
if($_SERVER['REMOTE_ADDR'])
{
$ip = $_SERVER['REMOTE_ADDR'];
}
else if ($_SERVER['HTTP_CLIENT_IP'] && $_SERVER['HTTP_CLIENT_IP']!='unknown')
{
$ip = $_SERVER['HTTP_CLIENT_IP'];
}
else if ($_SERVER['HTTP_X_FORWARDED_FOR'] && $_SERVER['HTTP_X_FORWARDED_FOR']!='unknown')
{
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
}
return $ip;
}
/**
* IP转成整形数值
* @param string $ip
* @return int
*/
public static function ipToInt($ip)
{
return sprintf("%u", ip2long($ip));
}
/**
* 判断IP是否在一个IP段内
* @param string $startIp 开始IP
* @param string $endIp 结束IP
* @param string $ip IP
* @return bool
*/
public static function isIn($startIp, $endIp, $ip)
{
$startInt = self::ipToInt($startIp);
$endInt = self::ipToInt($endIp);
$ipInt = self::ipToInt($ip);
return $ipInt>=$startInt && $ipInt<=$endInt;
}
}
?>