通过Ip纯真库获取地址详细信息
通过IpLocatoin.php(ip处理类) 及qqwry.dat(IP纯真),完整获取ip对应的详细地址
Tp5.1通过ip获取地址
public function getAddress(){$ip = request()->ip();$IpLocation = new IpLocation();$findProvince = $IpLocation->getlocation($ip);if($findProvince){$str = $findProvince['country'].'('.$findProvince['area'].')';}else{$str = "未知";}return $str;
}
地址处理类--需配合IP纯真库*(qqwry.dat)使用
<?php
namespace app\index\controller;
/** * IP 地理位置查询类 */
class IpLocation
{ /** * QQWry.Dat文件指针 * * @var resource */ private $fp; /** * 第一条IP记录的偏移地址 * * @var int */ private $firstip; /** * 最后一条IP记录的偏移地址 * * @var int */ private $lastip; /** * IP记录的总条数(不包含版本信息记录) * * @var int */ private $totalip; /** * 构造函数,打开 QQWry.Dat 文件并初始化类中的信息 * * @param string $filename */ public function __construct() { $filename = './static/other/qqwry.dat';$this->fp = 0; if (($this->fp = fopen($filename, 'rb')) !== false) { $this->firstip = $this->getlong(); $this->lastip = $this->getlong(); $this->totalip = ($this->lastip - $this->firstip) / 7; //注册析构函数,使其在程序执行结束时执行 register_shutdown_function(array( &$this, '__destruct' )); } } /** * 析构函数,用于在页面执行结束后自动关闭打开的文件。 * */ public function __destruct() { if ($this->fp) { fclose($this->fp); } $this->fp = 0; } /** * 返回读取的长整型数 * * @access private * @return int */ private function getlong() { //将读取的little-endian编码的4个字节转化为长整型数 $result = unpack('Vlong', fread($this->fp, 4)); return $result['long']; } /** * 返回读取的3个字节的长整型数 * * @access private * @return int */ private function getlong3() { //将读取的little-endian编码的3个字节转化为长整型数 $result = unpack('Vlong', fread($this->fp, 3) . chr(0)); return $result['long']; } /** * 返回压缩后可进行比较的IP地址 * * @access private * @param string $ip * @return string */ private function packip($ip) { // 将IP地址转化为长整型数,如果在PHP5中,IP地址错误,则返回False, // 这时intval将Flase转化为整数-1,之后压缩成big-endian编码的字符串 return pack('N', intval(ip2long($ip))); } /** * 返回读取的字符串 * * @access private * @param string $data * @return string */ private function getstring($data = "") { $char = fread($this->fp, 1); while (ord($char) > 0) { // 字符串按照C格式保存,以结束 $data .= $char; // 将读取的字符连接到给定字符串之后 $char = fread($this->fp, 1); } return iconv('gbk', 'utf-8', $data); } /** * 返回地区信息 * * @access private * @return string */ private function getarea() { $byte = fread($this->fp, 1); // 标志字节 switch (ord($byte)) { case 0: // 没有区域信息 $area = ""; break; case 1: case 2: // 标志字节为1或2,表示区域信息被重定向 fseek($this->fp, $this->getlong3()); $area = $this->getstring(); break; default: // 否则,表示区域信息没有被重定向 $area = $this->getstring($byte); break; } return $area; } /** * 根据所给 IP 地址或域名返回所在地区信息 * * @access public * @param string $ip * @return array */ public function getlocation($ip) { if (!$this->fp) return null; // 如果数据文件没有被正确打开,则直接返回空 $location['ip'] = gethostbyname($ip); // 将输入的域名转化为IP地址 $ip = $this->packip($location['ip']); // 将输入的IP地址转化为可比较的IP地址 // 不合法的IP地址会被转化为255.255.255.255 // 对分搜索 $l = 0; // 搜索的下边界 $u = $this->totalip; // 搜索的上边界 $findip = $this->lastip; // 如果没有找到就返回最后一条IP记录(QQWry.Dat的版本信息) while ($l <= $u) { // 当上边界小于下边界时,查找失败 $i = floor(($l + $u) / 2); // 计算近似中间记录 fseek($this->fp, $this->firstip + $i * 7); $beginip = strrev(fread($this->fp, 4)); // 获取中间记录的开始IP地址 // strrev函数在这里的作用是将little-endian的压缩IP地址转化为big-endian的格式 // 以便用于比较,后面相同。 if ($ip < $beginip) { // 用户的IP小于中间记录的开始IP地址时 $u = $i - 1; // 将搜索的上边界修改为中间记录减一 } else { fseek($this->fp, $this->getlong3()); $endip = strrev(fread($this->fp, 4)); // 获取中间记录的结束IP地址 if ($ip > $endip) { // 用户的IP大于中间记录的结束IP地址时 $l = $i + 1; // 将搜索的下边界修改为中间记录加一 } else { // 用户的IP在中间记录的IP范围内时 $findip = $this->firstip + $i * 7; break; // 则表示找到结果,退出循环 } } } //获取查找到的IP地理位置信息 fseek($this->fp, $findip); $location['beginip'] = long2ip($this->getlong()); // 用户IP所在范围的开始地址 $offset = $this->getlong3(); fseek($this->fp, $offset); $location['endip'] = long2ip($this->getlong()); // 用户IP所在范围的结束地址 $byte = fread($this->fp, 1); // 标志字节 switch (ord($byte)) { case 1: // 标志字节为1,表示国家和区域信息都被同时重定向 $countryOffset = $this->getlong3(); // 重定向地址 fseek($this->fp, $countryOffset); $byte = fread($this->fp, 1); // 标志字节 switch (ord($byte)) { case 2: // 标志字节为2,表示国家信息又被重定向 fseek($this->fp, $this->getlong3()); $location['country'] = $this->getstring(); fseek($this->fp, $countryOffset + 4); $location['area'] = $this->getarea(); break; default: // 否则,表示国家信息没有被重定向 $location['country'] = $this->getstring($byte); $location['area'] = $this->getarea(); break; } break; case 2: // 标志字节为2,表示国家信息被重定向 fseek($this->fp, $this->getlong3()); $location['country'] = $this->getstring(); fseek($this->fp, $offset + 8); $location['area'] = $this->getarea(); break; default: // 否则,表示国家信息没有被重定向 $location['country'] = $this->getstring($byte); $location['area'] = $this->getarea(); break; } if ($location['country'] == " CZ88.NET") { // CZ88.NET表示没有有效信息 $location['country'] = "未知"; } if ($location['area'] == " CZ88.NET") { $location['area'] = ""; } return $location; }
}
免费IP库下载
- 纯真官网地址
- 关注微信公众号(纯真IP实验室)下载
通过IpLocatoin.php(ip处理类) 及qqwry.dat(IP库),完整获取ip对应的详细地址
通过Ip纯真库获取地址详细信息相关推荐
- Go 使用IP纯真库获取IP对应的国家、省、市
创作不易感谢支持. 一条主写Go和PHP的小菜鸟.平常有时间喜欢自己写点东西,如有不对的地方,欢迎大佬指点. 个人博客:太阳上的雨天 地址:blog.caixiaoxin.cn 善于分享,希望有助他人 ...
- Python3 | 通过百度地图API获取商家详细信息(包括店名,地址,经纬度,电话)
一.打开百度地图开放平台,选择Web服务API . 官方文档对API接口的调用描述的比较详细,在调用之前先要申请百度地图的账号,然后申请密钥,获取密钥的步骤官方也有说明. 二.通过百度地图 ...
- PHP 获取服务器详细信息
PHP 获取系统信息,PHP 获取服务器详细信息 获取系统类型及版本号: php_uname() (例:Windows NT ...
- 淘宝/天猫API接口,item_sku - 淘宝商品SKU详细信息查询,淘宝/天猫获取sku详细信息 API 返回值说明
欢迎使用淘宝API接口(item_sku - 淘宝商品SKU详细信息查询 ) 你好! 这是你使用我们的淘宝API接口获取商品详细接口说明. 测试地址:获取Key和secret 测试结果: Reques ...
- 淘宝API接口:获取sku详细信息
今天分享的是淘宝平台API,item_sku - 获取sku详细信息 点击注册测试地址(获取Key和secret) { "item": { "num_iid": ...
- 淘宝/天猫如何获取sku API接口,item_sku - 获取sku详细信息
一.接口参数说明: 通过淘宝/天猫app中分享至PC端的短链接商品ID,通过调用item_sku - 获得sku接口,可以得到接口要的商品sku详情数据. 点击获取测试key和secret 请求地址: ...
- Android获取歌曲详细信息
Android获取歌曲详细信息 一.目标 二.实现方案 三.HTML方案 四.JSON方案 五.接下来 六.Finally 在<Android实现歌词笔记构思>时,构思了如何在笔记中添加歌 ...
- Lucene学习-深入Lucene分词器,TokenStream获取分词详细信息
Lucene学习-深入Lucene分词器,TokenStream获取分词详细信息 在此回复牛妞的关于程序中分词器的问题,其实可以直接很简单的在词库中配置就好了,Lucene中分词的所有信息我们都可以从 ...
- 微信小程序控制台 报错 对应的服务器证书无效 控制台输入 showRequestInfo() 可以获取更详细信息 原因是ssl证书过期 重新申请即可
微信小程序控制台 报错 对应的服务器证书无效.控制台输入 showRequestInfo() 可以获取更详细信息 报错原因:域名下的SSL证书过期 我这边报错的原因是ssl证书过期 重新申请后就好了, ...
最新文章
- Android LayoutInflater 的使用
- git diff Git查看版本改动
- oracle错误:ORA-12545
- Hexo自定义页面的两种方法
- json数据映射到html,在GoLang中将Json数据映射到Html模板
- 卸载angular版本
- 05.analysis-normalizer应用
- Harvard-X免费生物信息课程 (代码、文档、数据) - 适合系统学习
- 阿里云服务器——centos7下源码安装tomcat9
- 如何在 Mac 上下载 macOS Monterey public beta 6?
- 【算法笔记+BZOJ3676】回文串(回文树/回文自动机模版题)
- json文件格式转换为png文件格式
- android 打好的补丁位置,Android 6.0上打完第一个补丁后再打新补丁Crash
- clickHouse 使用常见问题踩坑
- 详解vue原理之观察模式Dep->Watcher
- 重装linux后没声音,安装虚拟机后没声音了
- 芝加哥大学校长:诺贝尔奖人才是怎样炼成的?
- 淘宝/天猫API:item_recommend-获取推荐商品列表
- java生命之树_珍惜生命的心得感想与体会
- UE4引擎源码学习笔记(一):源码整体文件结构