PHP获取客户端真实IP地址的5种情况分析和实现代码


Posted in PHP onJuly 08, 2014

在PHP获取客户端IP中常使用 $_SERVER["REMOTE_ADDR"] 。
(1) 但如果客户端是使用代理服务器来访问,那取到的是代理服务器的 IP 地址,而不是真正的客户端 IP 地址。要想透过代理服务器取得客户端的真实 IP 地址,就要使用 $_SERVER["HTTP_X_FORWARDED_FOR"] 来读取。
(2) 但只有客户端使用“透明代理”的情况下,$_SERVER["HTTP_X_FORWARDED_FOR"] 的值才是客户端真正的IP(如果是多层代理,该值可能是由客户端真正IP和多个代理服务器的IP组成,由逗号“,”分隔)。
(3) 而在“匿名代理”、“欺骗性代理”的情况下是代理服务器的IP值(如果是多层代理,该值可能由多个代理服务器的IP组成,由逗号“,”分隔)。
(4) 在“高匿名代理”的情况下是空值。

关于HTTP头信息中的REMOTE_ADDR、HTTP_FORWARDED_FOR值,分析如下,假设客户端真实IP是221.5.252.160:

 一、没有使用代理服务器的PHP获取客户端IP情况:

REMOTE_ADDR = 221.5.252.160

HTTP_VIA=没数值或者不显示

HTTP_X_FORWARDED_FOR = 没数值或不显示

二、使用透明代理服务器的情况:Transparent Proxies

REMOTE_ADDR = 最后一个代理服务器 IP

HTTP_VIA=代理服务器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_VIA=代理服务器IP

HTTP_X_FORWARDED_FOR = 代理服务器 IP (经过多个代理服务器时,这个值类似:203.98.182.163, 203.98.182.163, 203.129.72.215)

 这种情况下隐藏了客户端的真实IP,但是向访问对象透露了客户端是使用代理服务器访问它们的。

四、使用欺骗性代理服务器的情况:Distorting Proxies

REMOTE_ADDR = 代理服务器 IP

HTTP_VIA=代理服务器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_VIA=没数值或者不显示

 HTTP_X_FORWARDED_FOR = 没数值或不显示。

无论是REMOTE_ADDR还是HTTP_FORWARDED_FOR,这些头消息未必能够取得到,因为不同的浏览器不同的网络设备可能发送不同的IP 头消息。因此PHP使用$_SERVER["REMOTE_ADDR"] 、$_SERVER["HTTP_X_FORWARDED_FOR"] 获取的值可能是空值也可能是“unknown”值。

PHP获取客户端IP时另外一点需注意,使用函数getenv('HTTP_X_FORWARDED_FOR')或getenv('REMOTE_ADDR') 也可以如上代码一样取得同样的效果。但getenv()不支持在IIS的isapi方式下运行的PHP。

REMOTE_ADDR 是你的客户端跟你的服务器“握手”时候的IP。如果使用了“匿名代理”,REMOTE_ADDR将显示代理服务器的IP。

HTTP_CLIENT_IP 是代理服务器发送的HTTP头。如果是“超级匿名代理”,则返回none值。同样,REMOTE_ADDR也会被替换为这个代理服务器的IP。

$_SERVER['REMOTE_ADDR']; //访问端(有可能是用户,有可能是代理的)IP

$_SERVER['HTTP_CLIENT_IP'];  //代理端的(有可能存在,可伪造)

$_SERVER['HTTP_X_FORWARDED_FOR']; //用户是在哪个IP使用的代理(有可能存在,也可以伪造)

根据以上几种情况写出的PHP代码:

<?php

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'];  

 } 

}

?>
PHP 相关文章推荐
PHP的开合式多级菜单程序
Oct 09 PHP
在 PHP 中使用随机数的三个步骤
Oct 09 PHP
使用数据库保存session的方法
Oct 09 PHP
php字符串截取中文截取2,单字节截取模式
Dec 10 PHP
php foreach循环中使用引用的问题
Nov 06 PHP
php+mysqli预处理技术实现添加、修改及删除多条数据的方法
Jan 30 PHP
PHP加密解密函数详解
Oct 28 PHP
再推荐十款免费的php开发工具
Nov 09 PHP
分享50个提高PHP执行效率的技巧
Dec 26 PHP
PHP实现的62进制转10进制,10进制转62进制函数示例
Jun 06 PHP
Windows服务器中PHP如何安装redis扩展
Sep 27 PHP
PHP7 list() 函数修改
Mar 09 PHP
php+mysql不用递归实现的无限级分类实例(非递归)
Jul 08 #PHP
PHP生成短网址的3种方法代码实例
Jul 08 #PHP
PHP的fsockopen、pfsockopen函数被主机商禁用的解决办法
Jul 08 #PHP
php中函数前加&amp;符号的作用分解
Jul 08 #PHP
PHP实现的连贯操作、链式操作实例
Jul 08 #PHP
PHP类中的魔术方法(Magic Method)简明总结
Jul 08 #PHP
PHP的魔术常量__METHOD__简介
Jul 08 #PHP
You might like
模拟SQLSERVER的两个函数:dateadd(),datediff()
2006/10/09 PHP
查找mysql字段中固定字符串并替换的几个方法
2012/09/23 PHP
Yii2框架dropDownList下拉菜单用法实例分析
2016/07/18 PHP
php fseek函数读取大文件两种方法
2016/10/12 PHP
laravel开发环境homestead搭建过程详解
2020/07/03 PHP
用javascript获取当页面上鼠标光标位置和触发事件的对象的代码
2009/12/09 Javascript
js querySelector和getElementById通过id获取元素的区别
2012/04/20 Javascript
jQuery extend 的简单实例
2013/09/18 Javascript
FF IE浏览器修改标签透明度的方法
2014/01/27 Javascript
JavaScript模拟实现继承的方法
2015/03/30 Javascript
Javascript中的数据类型之旅
2015/10/18 Javascript
jQuery弹出遮罩层效果完整示例
2016/09/13 Javascript
浅谈JS之tagNaem和nodeName
2016/09/13 Javascript
Nodejs进阶:核心模块net入门学习与实例讲解
2016/11/21 NodeJs
JS之if语句对接事件动作逻辑(详解)
2017/06/28 Javascript
elemetUi 组件--el-upload实现上传Excel文件的实例
2017/10/27 Javascript
关于react-router/react-router-dom v4 history不能访问问题的解决
2018/01/08 Javascript
Vue项目安装插件并保存
2019/01/28 Javascript
详解Vue中的MVVM原理和实现方法
2020/07/15 Javascript
在vue中配置不同的代理同时访问不同的后台操作
2020/09/11 Javascript
浅谈JavaScript 声明提升
2020/09/14 Javascript
Python中使用ElementTree解析XML示例
2015/06/02 Python
Python爬虫之模拟知乎登录的方法教程
2017/05/25 Python
Flask模板引擎之Jinja2语法介绍
2019/06/26 Python
对python中的os.getpid()和os.fork()函数详解
2019/08/08 Python
Python模拟登录之滑块验证码的破解(实例代码)
2019/11/18 Python
Python如何绘制日历图和热力图
2020/08/07 Python
时装界的“朋克之母”:Vivienne Westwood
2017/07/06 全球购物
美国独家设计师眼镜在线光学商店:Glasses Gallery
2017/12/28 全球购物
软件测试常见笔试题
2012/02/04 面试题
Servlet如何得到客户端机器的信息
2014/10/17 面试题
上课玩手机检讨书
2014/02/08 职场文书
2015年幼儿园毕业感言
2014/02/12 职场文书
银行求职信
2014/05/31 职场文书
工作简报格式范文
2015/07/21 职场文书
win10截图快捷键win+shift+s没有反应无法截图怎么解决?
2022/08/14 数码科技