PHP获取用户客户端真实IP的解决方案


Posted in PHP onOctober 10, 2016

获取客户端ip其实不是个简单的活儿,因为存在Ip欺骗,和代理问题,所以获取客户端的IP的真实性会打折扣的,不能百分百准确.但是我们还是尽量找一个比较完善的获取客户端真正ip方法.使用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_FOR = 代理服务器 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 相关文章推荐
PHP 七大优势分析
Jun 23 PHP
PHP连接局域网MYSQL数据库的简单实例
Aug 26 PHP
php另类上传图片的方法(PHP用Socket上传图片)
Oct 30 PHP
PHP json_decode函数详细解析
Feb 17 PHP
PHP定时执行任务实现方法详解(Timer)
Jul 30 PHP
PHP命令行执行整合pathinfo模拟定时任务实例
Aug 12 PHP
php版微信公众号自定义分享内容实现方法
Sep 22 PHP
Zend Framework数据库操作方法实例总结
Dec 11 PHP
PHP基于ORM方式操作MySQL数据库实例
Jun 21 PHP
PHP自动识别当前使用移动终端
May 21 PHP
PHP实现的多维数组去重操作示例
Jul 21 PHP
php设计模式之职责链模式实例分析【星际争霸游戏案例】
Mar 27 PHP
php表单加入Token防止重复提交的方法分析
Oct 10 #PHP
Laravel5中防止XSS跨站攻击的方法
Oct 10 #PHP
php中让人头疼的浮点数运算分析
Oct 10 #PHP
Laravel实现自定义错误输出内容的方法
Oct 10 #PHP
PHP定时任务获取微信access_token的方法
Oct 10 #PHP
php使用SAE原生Mail类实现各种类型邮件发送的方法
Oct 10 #PHP
PHP简单数据库操作类实例【支持增删改查及链式操作】
Oct 10 #PHP
You might like
php代码审计比较有意思的例子
2014/05/07 PHP
yii添删改查实例
2015/11/16 PHP
调试WordPress中定时任务的相关PHP脚本示例
2015/12/10 PHP
判断是否输入完毕再激活提交按钮
2006/06/26 Javascript
会自动逐行上升的文本框
2006/06/30 Javascript
通过JS自动隐藏手机浏览器的地址栏实现原理与代码
2013/01/02 Javascript
javascipt基础内容--需要注意的细节
2013/04/10 Javascript
实例说明为什么不要行内使用javascript
2014/04/18 Javascript
jQuery选择器之基本选择器与层次选择器
2015/03/03 Javascript
轻量级jQuery插件slideBox实现带底栏轮播(焦点图)代码
2016/03/28 Javascript
Vue系列:通过vue-router如何传递参数示例
2017/01/16 Javascript
js验证手机号、密码、短信验证码代码工具类
2020/06/24 Javascript
node.js实现复制文本到剪切板的功能
2017/01/23 Javascript
JS实现十分钟倒计时代码实例
2018/10/18 Javascript
一个因@click.stop引发的bug的解决
2019/01/08 Javascript
微信小程序实现一张或多张图片上传(云开发)
2019/09/25 Javascript
vue2.0 获取从http接口中获取数据,组件开发,路由配置方式
2019/11/04 Javascript
vue中使用echarts的示例
2021/01/03 Vue.js
antdesign-vue结合sortablejs实现两个table相互拖拽排序功能
2021/01/08 Vue.js
Python对文件和目录进行操作的方法(file对象/os/os.path/shutil 模块)
2017/05/08 Python
朴素贝叶斯Python实例及解析
2018/11/19 Python
Python利用WMI实现ping命令的例子
2019/08/14 Python
Python散点图与折线图绘制过程解析
2019/11/30 Python
Python类如何定义私有变量
2020/02/03 Python
细数nn.BCELoss与nn.CrossEntropyLoss的区别
2020/02/29 Python
意大利网上购书网站:Libraccio.it
2021/02/03 全球购物
秘书行业自我鉴定范文
2013/12/30 职场文书
管理失职检讨书
2014/02/12 职场文书
党校个人自我鉴定范文
2014/03/28 职场文书
指导教师评语
2014/04/26 职场文书
小组名称和口号
2014/06/09 职场文书
先进工作者申报材料
2014/12/23 职场文书
社区低保工作总结2015
2015/07/23 职场文书
奖学金申请书(范文)
2019/08/14 职场文书
mysql left join快速转inner join的过程
2021/06/30 MySQL
Javascript的promise,async和await的区别详解
2022/03/24 Javascript