布尔教育 PHP教学笔记
【功能主治】
对获取来访者IP不是很了解的同学,以及在获取的过程中出现问题的同学。
痴迷于研究获取访客IP地址一劳永逸的方法者
【不良反应】
如果没有PHP基础知识和简单的HTTP知识,可能会出现头晕,恶心等反应
很多朋友都有自己的技术博客,用来记录自己的学习历程和经验总结之用。经过慢慢地积累,博客内容丰富了,每天的IP数量也在暴增。
这个时候你可能会思考,我的这些访客主要来自哪里?有没有来自国外的呢?这些人都用什么浏览器(进而分析是技术人员多一些还是小白多一些)?什么操作系统?
基于这样的一个需求点,我们来给大家讲解这其中的一些技术点。
授人以渔
我们不是简单地给你~~一个函数~~,也不是给你~~一个类~~,我们是认真地讲解这其中的原理,让你自己能够去封装函数,甚至是类。
1、正常情况下获取访客的IP
说到获取来访者的IP很多童鞋自然想到了那个超全局变量数组$_SERVER。
$ip = $_SERVER[‘REMOTE_ADDR‘];
但是在微软的IIS服务器下,就无法获取IP了,这个时候你需要使用IIS服务器的全局变量HTTP_CLIENT_IP,因为REMOTE_ADDR不好使了。
$ip = $_SERVER[‘HTTP_CLIENT_IP‘];
讲到了这里新的问题又来了,有的用户是通过代理来上的网,那么这个时候你如何解决总是获取PROXY的地址的尴尬局面呢?
不要担心,这个时候我们可以问代理服务器去要访客的真实IP,简言之,就是让代理服务器在替访客请求我的服务器的时候,携带上那位访客的IP,并为其取名HTTP_X_FORWARDED_FOR,这样我的服务器通过获取代理服务器传过来的全局变量$_SERVER[‘HTTP_X_FORWARDED_FOR‘],不正是访客的IP吗?
$realip = $_SERVER[‘HTTP_X_FORWARDED_FOR‘];
2、非正常情况下获取访客IP
这里我们说到的非正常情况就是,全局变量数组被关闭。因为涉及到了服务器的安全问题,毕竟$_SERVER数组暴露太多服务器的隐私。
那关闭后,不能通过$_SERVER数组获取访客IP了,怎么办?
假如生活欺骗了你,不要悲伤,不要心急!忧郁的日子里须要镇静!!!
不要怕,PHP官方小组给了我们一个锦囊,待我慢慢拆开
string getenv ( string $varname ) getenv — 获取一个环境变量的值,使用 phpinfo() 你可以看到所有环境变量的列表。 返回环境变量 varname 的值, 如果环境变量 varname 不存在则返回 FALSE。
对,就是这个getenv()函数,它能解决无法访问$_SERVER的问题。
// 使用代理服务器访问的情况下 $realip = getenv("HTTP_X_FORWARDED_FOR"); // 正常Apache Web服务器环境下 $ip = getenv("REMOTE_ADDR"); // IIS Web服务器环境下 $ip = getenv("HTTP_CLIENT_IP");
好了这些情况,我们都跟大家讲清楚了,那么接下来我们就来封装那个一劳永逸的方法。
封装获取访客真实IP地址的方法
<?php /** * @author DengPeng <[email protected]> * @since 2016/11/30 * @copyright copyright (c) 2016 zixue.it GPL * @license http://www.zixue.it/ */ /** * 获取访客的真实IP * @return mixed 查询出结果就返回ip字符串,否则返回null * 2016-11-30T15:22:19+0800 */ function getIp() { $ip = null; // 1、判断服务器是否开放全局变量数组权限 if (isset($_SERVER)) { if (isset($_SERVER[‘HTTP_X_FORWARDED_FOR‘])) { // 1.1、代理环境下 $ip = $_SERVER[‘HTTP_X_FORWARDED_FOR‘]; } else if (isset($_SERVER[‘HTTP_CLIENT_IP‘])) { // 1.2、IIS服务器环境下 $ip = $_SERVER[‘HTTP_CLIENT_IP‘]; } else { // 1.3、Apache服务器环境下 $ip = $_SERVER[‘REMOTE_ADDR‘]; } } else { // 2、服务器关闭全局变量数组访问权限 if (getenv($_SERVER[‘HTTP_X_FORWARDED_FOR‘])) { $ip = getenv($_SERVER[‘HTTP_X_FORWARDED_FOR‘]); } else if (getenv("HTTP_CLIENT_IP")) { $ip = getenv("HTTP_CLIENT_IP"); } else { $ip = getenv("REMOTE_ADDR"); } } // 返回访客真实IP return $ip; } ?>
封装获取访客的浏览器、操作系统、地理位置等信息的类
前面我们只是在获取用户IP的基础上进行了重用性函数的封装,那么接下来我们要给大家封装一个实用的类,通过这个类,你能灵活地获取用户的浏览器、操作系统、地理位置等信息。
<?php /** * @author DengPeng <[email protected]> * @since 2016/11/30 * @copyright copyright (c) 2016 zixue.it GPL * @license http://www.zixue.it/ */ class VisitorInfo { // 定义浏览器类型 static public $browser = null; // 定义操作系统类型 static public $os = null; // 定义访客IP static public $ip = null; // 定义访客位置 static public $location = null; /** * 获取浏览器信息 * @access public * @return string 返回浏览器信息 * 2016-11-30T16:07:54+0800 */ static public function getBrowser() { // 获取访客浏览器信息 if (isset($_SERVER)) { self::$browser = $_SERVER[‘HTTP_USER_AGENT‘]; } else { self::$browser = getenv(‘HTTP_USER_AGENT‘); } // 匹配访客浏览器类型 if (preg_match(‘/firefox/i‘, self::$browser)) { self::$browser = ‘FireFox‘; } else if (preg_match(‘/chrome/i‘, self::$browser)) { self::$browser = ‘Chrome‘; } else if (preg_match(‘/opera/i‘, self::$browser)) { self::$browser = ‘Opera‘; } else { self::$browser = ‘Other‘; } return self::$browser; } /** * 获取访客操作系统类型 * @access public * @return string 返回操作系统的类型 * 2016-11-30T16:11:40+0800 */ static public function getOs() { // 获取访客操作系统信息 if (isset($_SERVER)) { self::$os = $_SERVER[‘HTTP_USER_AGENT‘]; } else { self::$os = getenv(‘HTTP_USER_AGENT‘); } // 匹配访客操作系统类型 if (preg_match(‘/win/i‘, self::$os)) { self::$os = ‘Windows‘; } else if (preg_match(‘/linux/i‘, self::$os)) { self::$os = ‘Linux‘; } else if (preg_match(‘/mac/i‘, self::$os)) { self::$os = ‘Mac‘; } else { self::$os = ‘Other‘; } // 返回访客的操作系统类型 return self::$os; } /** * 获取访客的ip地址 * @access public * @return string 返回访客的ip地址 * 2016-11-30T16:27:01+0800 */ static public function getIp() { // 1、判断服务器是否开放全局变量数组权限 if (isset($_SERVER)) { if (isset($_SERVER[‘HTTP_X_FORWARDED_FOR‘])) { // 1.1、代理环境下 self::$ip = $_SERVER[‘HTTP_X_FORWARDED_FOR‘]; } else if (isset($_SERVER[‘HTTP_CLIENT_IP‘])) { // 1.2、IIS服务器环境下 self::$ip = $_SERVER[‘HTTP_CLIENT_IP‘]; } else { // 1.3、Apache服务器环境下 self::$ip = $_SERVER[‘REMOTE_ADDR‘]; } } else { // 2、服务器关闭全局变量数组访问权限 if (getenv($_SERVER[‘HTTP_X_FORWARDED_FOR‘])) { self::$ip = getenv($_SERVER[‘HTTP_X_FORWARDED_FOR‘]); } else if (getenv("HTTP_CLIENT_IP")) { self::$ip = getenv("HTTP_CLIENT_IP"); } else { self::$ip = getenv("REMOTE_ADDR"); } } // 返回访客的ip return self::$ip; } /** * 获取访客的地址和ISP(因特网服务提供商) * @access public * @return sting 返回访客的地址和ISP * 2016-11-30T16:40:06+0800 */ static public function getLocation() { // 获取访客IP self::getIp(); // self::$ip = ‘116.243.183.60‘; // 临时测试IP // 利用淘宝IP地址池接口,获得访客的位置 $url = "http://ip.taobao.com/service/getIpInfo.php?ip=". self::$ip; $info = json_decode(file_get_contents($url)); if ($info->code) { return false; } else { $str = $info->data->country . $info->data->area . $info->data->city . ‘,‘ . $info->data->isp; return $str; } } } ?>
对获取访客的真实IP地址有了基础的了解,然后我们又一起封装了获取IP的函数和获取访客一些信息的类。我相信有了这些知识的巩固,你一定有办法去认识统计你的访客信息。