怎么使用PHP获取用户客户端真实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);
现在需要对这段代码进行解释,这里用到了两个函数,getenv()和strcasecmp(),前一个函数获取得系统的环境变量,如果能取到值,则返回该值,不能则返回false.
$_SERVER 是服务器超级全局变量数组,用 $_SERVER['REMOTE_ADDR'] 同样可以获取到客户端的IP地址.二者的区别在于, getenv 不支持IIS的isapi方式运行的php.
strcasecmp(string1,string2) 字符串函数的用法是把 string1 和 string2 进行比较,如果相等返回0,如果 string1 大于 string2 ,返回大于0的数,小于则返回小于0的数.
函数先使用客户IP,如果不成立尝试用代理的方法,如果不行,再使用 REMOTE_ADDR .
还看到过一个检测IP更详细的方法,考虑了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
HTTP_X_FORWARDED_FOR = 客户端真实 IP (经过多个代理服务器时,这个值类似:221.5.252.160, 203.98.182.163, 203.129.72.215)
这类代理服务器还是将客户端真实的IP发送给了访问对象,无法达到隐藏真实身份的目的.
三、使用普通匿名代理服务器的PHP获取客户端IP情况:Anonymous Proxies
REMOTE_ADDR = 最后一个代理服务器 IP
HTTP_X_FORWARDED_FO R = 代理服务器 IP (经过多个代理服务器时,这个值类似:203.98.182.163, 203.98.182.163, 203.129.72.215)
这种情况下隐藏了客户端的真实IP,但是向访问对象透露了客户端是使用代理服务器访问它们的.
四、使用欺骗性代理服务器的情况:Distorting Proxies
REMOTE_ADDR = 代理服务器 IP
HTTP_X_FORWARDED_FOR = 随机的 IP(经过多个代理服务器时,这个值类似:220.4.251.159, 203.98.182.163, 203.129.72.215)
这种情况下同样透露了客户端是使用了代理服务器,但编造了一个虚假的随机IP(220.4.251.159)代替客户端的真实IP来欺骗它.
五、使用高匿名代理服务器的PHP获取客户端IP情况:High Anonymity Proxies (Elite proxies)
REMOTE_ADDR = 代理服务器 IP
HTTP_X_FORWARDED_FOR
= 没数值或不显示
无论是 REMOTE_ADDR 还是 HTTP_FORWARDED_FOR ,这些头消息未必能够取得到,因为不同的浏览器不同的网络设备可能发送不同的IP头消息.因此PHP使用$_SERVER["REMOTE_ADDR"] 、$_SERVER["HTTP_X_FORWARDED_FOR"] 获取的值可能是空值也可能是“unknown”值.
怎么使用PHP获取用户客户端真实IP的解决方案呢?的更多相关文章
- PHP获取用户客户端真实IP的解决方案是怎样呢?
function getIp(){if (getenv("HTTP_CLIENT_IP") && strcasecmp(getenv("HTTP_CLIE ...
- 获取用户的真实ip
常见的坑有两个: 一.获取的是内网的ip地址.在nginx作为反向代理层的架构中,转发请求到php,java等应用容器上.结果php获取的是nginx代理服务器的ip,表现为一个内网的地址.php获取 ...
- 深入nginx之《获取用户的真实IP》
获取用户的真实IP Nginx会将客户端的IP信息存放在$remote_addr变量里,但这并不意味着它就是客户端的IP,生产环境往往会充满各种代理,让IP的来龙去脉变得扑朔迷离. 目前互联网公司基本 ...
- PHP获取用户的真实IP地址
本文出至:新太潮流网络博客 PHP获取用户的真实IP地址,非代理IP function getClientIP(){ global $ip; if(getenv("HTTP_CLIENT_I ...
- Nginx 反向代理时获取用户的真实 IP
在平时我们开发后端程序的过程中,应该多多少少都会碰到记录客户端 IP 的场景,例如我之前写过的 APP 用户的一个审计功能,就需要获取用户的 IP 地址:还有广告系统里面,也是需要获取用户的 IP 地 ...
- 如何获取用户的真实IP
在JSP里,获取客户端的IP地址的方法是:request.getRemoteAddr(),这种方法在大部分情况下都是有效的.但是在通过了 Apache,Nagix等反向代理软件就不能获取到客户端的真实 ...
- 在PHP中如何获取用户的真实IP
/** * 获得用户的真实IP地址 * * @access public * @return string */ function real_ip() { static $realip = NULL; ...
- PHP获取远程客户端真实IP的办法!
(1).REMOTE_ADDR:浏览当前页面的用户计算机的ip地址 (2).HTTP_X_FORWARDED_FOR: 浏览当前页面的用户计算机的网关 (3).HTTP_CLIENT_IP:客户端的i ...
- X-Forwarded-For 负载均衡 7 层 HTTP 模式获取来访客户端真实 IP 的方法(IIS/Apache/Nginx/Tomcat)
https://help.aliyun.com/knowledge_detail/13051859.html?pos=1 1.IIS 6 配置方案2.IIS 7 配置方案3.Apache 配置方案4. ...
随机推荐
- [BS-15] Values of type 'NSInteger' should not be used as format arguments
Values of type 'NSInteger' should not be used as format arguments 苹果app支持arm64以后会有一个问题:NSInteger变成64 ...
- [BS-06] 设置release发布时NSLog不打印设置
设置release发布时NSLog不打印设置 前提:在XCode做开发调试时往往需要打印一些调试信息做debug用,大家知道当打印信息的地方多了之后在模拟器上跑可能不会有什么问题,因为模拟器用的是电脑 ...
- python set add 导致问题 TypeError: unhashable type: 'list'
问题复现 >>> a = set() >>> b = set() >>> b.add(1) >>> a.add(b) Trace ...
- 转:DLL如何导出C++的类
由于DLL的出现是针对C语言的,本身对C++的支持不够好.所以如何从DLL中导出C++的类作为DLL的API的一部分就成了问题. 我试了一下 class __declspec(dllexport) F ...
- HTML-移动端如何使用css让百分比布局的弹窗水平和垂直方向上居中
pc端让一个弹窗水平和垂直方向居中,在知道弹窗宽高的情况下很好计算,只需要用如下css即可: #date{ width: 300px; height: 300px; position: absolut ...
- SQL Server Index详解
最近在进行数据库调优,对索引的使用和其内部的运转一知半解.在园子里看到一篇相关文章非常好.留下印记以便日常查找. http://www.cnblogs.com/xwdreamer/archive/20 ...
- mysql:innodb monitor(show engine innodb status)探秘
在旧的版本里面是show innodb status命令,新版本后改动了一些:show engine innodb status; 我们最熟悉的,应当就是show innodb status命令,可以 ...
- zjuoj 3609 Modular Inverse
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3609 Modular Inverse Time Limit: 2 Seco ...
- Spring之我见
Spring 是什么(1) •Spring 是一个开源框架. •Spring 为简化企业级应用开发而生. 使用 Spring 可以使简单的 JavaBean 实现以前只有 EJB 才能实现的功能. • ...
- 自动开票-不能获取汇款地址 Cannot get remit to address
1. Cannot get remit to address 1. 查看客户Bill-to Address的Country信息; 2. 选择Receivable Manager职责,通过路径Setup ...