获取访客 IP 的正确姿势
Chinese Valentine's Day
1 、先看下教科书上获取 IP 的姿势:
$_SERVER["REMOTE_ADDR"]
2 、但是网上很多教程说上面的姿势不完善,还要解锁一下 36 式全方位姿势:
$user_IP = ($_SERVER["HTTP_VIA"]) ? $_SERVER["HTTP_X_FORWARDED_FOR"] : $_SERVER["REMOTE_ADDR"]; $user_IP = ($user_IP) ? $user_IP : $_SERVER["REMOTE_ADDR"];
3 、甚至还有 360 式的更全面的姿势:
function _get_client_ip() { $clientip = ''; if(getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'), 'unknown')) { $clientip = getenv('HTTP_CLIENT_IP'); } elseif(getenv('HTTP_X_FORWARDED_FOR') && strcasecmp(getenv('HTTP_X_FORWARDED_FOR'), 'unknown')) { $clientip = getenv('HTTP_X_FORWARDED_FOR'); } elseif(getenv('REMOTE_ADDR') && strcasecmp(getenv('REMOTE_ADDR'), 'unknown')) { $clientip = getenv('REMOTE_ADDR'); } elseif(isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown')) { $clientip = $_SERVER['REMOTE_ADDR']; } preg_match("/[\d.]{7,15}/", $clientip, $clientipmatches); $clientip = $clientipmatches[0] ? $clientipmatches[0] : 'unknown'; return $clientip; }
函数解析
那么究竟应该用哪种呢?我们先来看下 REMOTE_ADDR 、 HTTP_X_FORWARDED_FOR 、 HTTP_CLIENT_IP 是什么。 REMOTE_ADDR 访客 IP ,如果使用代理访问则显示代理 IP HTTP_X_FORWARDED_FOR 访客 IP ,如果不使用代理访问则为空 HTTP_CLIENT_IP 代理服务器 IP ,如果不使用代理访问则为空 注意 REMOTE_ADDR 是无法更改的,而 HTTP_X_FORWARDED_FOR 、 HTTP_CLIENT_IP 是由客户端(一般指代理服务器)自行设定的。
方法解决
1
那么我们应该根据不同的需求去使用上面的 IP : 一、投票系统防刷票 此时应该使用上面的方法 1 去获取客户 IP ,因为方法 2 和方法 3 获取到的 HTTP_X_FORWARDED_FOR 、 HTTP_CLIENT_IP 有可能是刷票者伪造的。 二、网站访问统计 此时应该使用方法 2 或者方法 3 获取客户 IP ,以便访客通过代理服务器访问网站时能获取到访客的真实 IP
最后要注意的是,存进数据库前别忘记过滤一下:
preg_replace( '/[^0-9a-fA-F:., ]/', '',$_SERVER['REMOTE_ADDR'] )
2 源码解析