ThinkPHP---TP拓展之获取IP信息
【概论】
(1)简述
在所有网站里,特别是用户管理系统,都喜欢记录用户访问的IP地址。对后期的业务开展有很大的意义,可以通过IP地址的记录访问出国内或全球范围内,哪一块用户比较多。
在后期做产品时,可以针对这块来重点推销。所以不要只将IP看为地址信息,认为没有什么用。
(2)获取IP方法
①原生PHP里通过超全局变量:$_SERVER保存关于报头、路径、脚本位置等信息。例如
注意:$_SERVER方法缺点---->有时获取不太准确
$_SERVER['SERVER_ADDR'] | 返回当前运行脚本所在的服务器的 IP 地址。 |
$_SERVER['SERVER_NAME'] | 返回当前运行脚本所在的服务器的主机名(比如 www.w3school.com.cn)。 |
其他具体的我在文章最后列出
②ThinkPHP封装了get_slient_ip(获取客户IP)方法来获取IP,准确来说,因为$_SERVER方法获取不太准确,所以该方法是对原生$_SERVER的补充完善
位置:系统函数库文件里function.php,接下来看下源码
/** * 获取客户端IP地址 * @param integer $type 返回类型 0 返回IP地址 1 返回IPV4地址数字 * @param boolean $adv 是否进行高级模式获取(有可能被伪装) * @return mixed */ function get_client_ip($type = 0,$adv=false) { $type = $type ? 1 : 0; static $ip = NULL; if ($ip !== NULL) return $ip[$type]; if($adv){ if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { $arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']); $pos = array_search('unknown',$arr); if(false !== $pos) unset($arr[$pos]); $ip = trim($arr[0]); }elseif (isset($_SERVER['HTTP_CLIENT_IP'])) { $ip = $_SERVER['HTTP_CLIENT_IP']; }elseif (isset($_SERVER['REMOTE_ADDR'])) { $ip = $_SERVER['REMOTE_ADDR']; } }elseif (isset($_SERVER['REMOTE_ADDR'])) { $ip = $_SERVER['REMOTE_ADDR']; } // IP地址合法验证 $long = sprintf("%u",ip2long($ip)); $ip = $long ? array($ip, $long) : array('0.0.0.0', 0); return $ip[$type]; }
输出查看下
echo get_client_ip();
浏览器输出结果:
若检验方法里传入数字1,则会输出IP对应的数字地址,这里验证下----->echo get_client_ip(1);
浏览器输出结果:
什么是数字地址呢?其实简单理解就是IP地址的数字格式,等价于IP地址。这里在浏览器输入数字地址2130706433验证下,会发现会显示出localhost界面。具体后面有解释
总结:对于方法get_client_id(可选参数数字)总结
1. 如果参数是0或者空,则表示返回正常的ipv4(127.0.0.1)地址,常见的正常的4段地址;
2. 如果参数为1,则会返回数字地址
【三】重点:TP中的使用--------------在ThinkPHP里将ip地址转换为物理地址
(1)什么是物理地址?
物理地址就是可以一眼看出IP所属地域,如下格式:
(2)重点:如何将IP地址转化为物理地址?
1. 转换原因:原因不多讲,说下应用吧---例如网络犯罪后快速定位
对于上面快速定位,这里补充下为什么黑客攻击后可以全身而退?因为黑客攻击服务器后,将历史记录删除了,直接删除了日志。
在ThinkPHP里系统提供了一个工具类来实现转换,但系统不提供所使用的数据。所以相关的数据库还需要开发人员去寻找对应数据库,数据库可以从纯真官网(www.cz88.net)去寻找。现在国内所有IP数据库基本都下载自纯真网,因为更新十分频繁,基本5天更新一次
2. 下载安装IP数据库
3. 测试:输入上面百度查询的IP
4. 因为PHP无法直接调取纯真的接口,所以需要另想办法~~~
5. 右击打开文件位置,找到qqwry.dat便是我们所需数据库
6. ThinkPHP里提供的类ThinkPHP\Library\Org\Net\locatiom.class.php,接下来看下源码
①构造方法
/** * 构造函数,打开 QQWry.Dat 文件并初始化类中的信息 * * @param string $filename * @return IpLocation */ public function __construct($filename = "UTFWry.dat") { $this->fp = 0; if (($this->fp = fopen(dirname(__FILE__).'/'.$filename, 'rb')) !== false) { $this->firstip = $this->getlong(); $this->lastip = $this->getlong(); $this->totalip = ($this->lastip - $this->firstip) / 7; } }
由源码即可分析出,IP文件位置应该和类文件同级。实例化时可以传递一个文件名,文件名所在位置和当前类属于同级目录
②getlocation方法:根据ip地址或域名返回所在地区信息
public function getlocation($ip='') {...}
分析后即可得知,该方法可以传入一个参数即ip地址,如果为空则表示查询当前用户的ip地址
③析构函数:用于页面执行结束后自动关闭打开的文件,所以不需要调用
public function __destruct() { if ($this->fp) { fclose($this->fp); } $this->fp = 0; }
分析代码总结:需要调用的方法有两个,①实例化时调用构造函数;②getlocation返回地区信息
(3)开始编写方法
1. 先将qqwry.dat复制到IpLocation.class同级目录下
2. 输出ip验证
$ip = new \Org\Net\IpLocation('qqwry.dat');//PS:这里我改用UTFWry.dat $location = $ip->getlocation('218.79.93.194'); dump($location);die;
输出结果:
array(5) { ["ip"] => string(13) "218.79.93.194" ["beginip"] => string(11) "218.79.93.0" ["endip"] => string(13) "218.79.94.255" ["country"] => string(18) "上海市普陀区" ["area"] => string(20) "/静安区电信ADSL" }
这里我调整了一下,因为qqwry.dat无法获取,所以查阅了一下,我改用UTFWry地址进行IP定位,具体我在文章thinkphp获取ip地址及位置信息里做了总结
UTFWry是默认的,不过也需要下载。这里我试过自定义的无效。。。。。。以后有时间再研究研究,备注下
拓展:
后期会结合接口编程,去开发,这里先了解下。将上述代码做下修改
// 实例化类 参数表示IP地址库文件 $ip = new \Org\Net\IpLocation('UTFWry.dat');
//通过I方法接收ip,然后传递ip $ipInfo = I('get.ip'); // 获取某个IP地址所在的位置 $location = $ip->getlocation($ipInfo); dump($location);die;
改写完成后将之前的访问连接http://www.1336.com/index.php/Admin/Doc/showList.html后面加上get传参,例如?ip=6.6.6.6,便可以访问对应IP(一般好的IP地址都被大佬级别的公司和集团占了,,,)。IP为6.6.6.6的输出结果:美国国防部IP
array(5) { ["ip"] => string(7) "6.6.6.6" ["beginip"] => string(7) "6.1.0.0" ["endip"] => string(13) "6.255.255.255" ["country"] => string(6) "美国" ["area"] => string(57) "亚利桑那州华楚卡堡市美国国防部网络中心" }
【拓展】
(1) 数字地址
元素/代码 | 描述 |
---|---|
$_SERVER['PHP_SELF'] | 返回当前执行脚本的文件名。 |
$_SERVER['GATEWAY_INTERFACE'] | 返回服务器使用的 CGI 规范的版本。 |
$_SERVER['SERVER_ADDR'] | 返回当前运行脚本所在的服务器的 IP 地址。 |
$_SERVER['SERVER_NAME'] | 返回当前运行脚本所在的服务器的主机名(比如 www.w3school.com.cn)。 |
$_SERVER['SERVER_SOFTWARE'] | 返回服务器标识字符串(比如 Apache/2.2.24)。 |
$_SERVER['SERVER_PROTOCOL'] | 返回请求页面时通信协议的名称和版本(例如,“HTTP/1.0”)。 |
$_SERVER['REQUEST_METHOD'] | 返回访问页面使用的请求方法(例如 POST)。 |
$_SERVER['REQUEST_TIME'] | 返回请求开始时的时间戳(例如 1577687494)。 |
$_SERVER['QUERY_STRING'] | 返回查询字符串,如果是通过查询字符串访问此页面。 |
$_SERVER['HTTP_ACCEPT'] | 返回来自当前请求的请求头。 |
$_SERVER['HTTP_ACCEPT_CHARSET'] | 返回来自当前请求的 Accept_Charset 头( 例如 utf-8,ISO-8859-1) |
$_SERVER['HTTP_HOST'] | 返回来自当前请求的 Host 头。 |
$_SERVER['HTTP_REFERER'] | 返回当前页面的完整 URL(不可靠,因为不是所有用户代理都支持)。 |
$_SERVER['HTTPS'] | 是否通过安全 HTTP 协议查询脚本。 |
$_SERVER['REMOTE_ADDR'] | 返回浏览当前页面的用户的 IP 地址。 |
$_SERVER['REMOTE_HOST'] | 返回浏览当前页面的用户的主机名。 |
$_SERVER['REMOTE_PORT'] | 返回用户机器上连接到 Web 服务器所使用的端口号。 |
$_SERVER['SCRIPT_FILENAME'] | 返回当前执行脚本的绝对路径。 |
$_SERVER['SERVER_ADMIN'] | 该值指明了 Apache 服务器配置文件中的 SERVER_ADMIN 参数。 |
$_SERVER['SERVER_PORT'] | Web 服务器使用的端口。默认值为 “80”。 |
$_SERVER['SERVER_SIGNATURE'] | 返回服务器版本和虚拟主机名。 |
$_SERVER['PATH_TRANSLATED'] | 当前脚本所在文件系统(非文档根目录)的基本路径。 |
$_SERVER['SCRIPT_NAME'] | 返回当前脚本的路径。 |
$_SERVER['SCRIPT_URI'] | 返回当前页面的 URI。 |