PHP统计应用开发之IP地址对应地理位置的实现,文章带全球IP地址MYSQL数据库备份文件
发表人:金马 | 2022-11-17

在做互联网技术开发中经常会需要用到IP地址对应地址位置的功能。

大部分情况会选择使用大厂API实现,大厂API无论在性能,速度上都非常好,但唯一缺点就是调用收费,大厂一般会提供1000次左右免费查询,但后期需要按量收费,一个中度流量应用一年下来费用在千元左右。

几个接口商的API测试,如ATB等,调用速度还是非常稳定,缺点就是在调用量大时费用也随着直线上升。

为了研究技术精神(省钱),所以决定自己开发实现,首先在网上找到全球IP地址数据库,导入MYSQL后大概有70万的数据量,备份文件在文章尾部提供下载。

先贴上在应用中的最终效果图:

image.png

实现方法:

根据用户的IP地址显示地理信息。

先建好IP地址库的数据表,表的结构如下:

CREATE TABLE IF NOT EXISTS `ui_ip` (
  `id` int(11) NOT NULL,
  `s_ip` varchar(255) DEFAULT NULL,
  `e_ip` varchar(255) DEFAULT NULL,
  `u_s_ip` bigint(11) DEFAULT NULL,
  `u_e_ip` bigint(11) DEFAULT NULL,
  `a1` varchar(255) DEFAULT NULL,
  `a2` varchar(255) DEFAULT NULL,
  `a3` varchar(255) DEFAULT NULL,
  `a4` varchar(255) DEFAULT NULL,
  `a5` varchar(255) DEFAULT NULL,
  `a6` varchar(255) DEFAULT NULL,
  `a7` varchar(255) DEFAULT NULL,
  `a8` varchar(255) DEFAULT NULL,
  `state` varchar(255) DEFAULT NULL,
  `lon` decimal(20,6) DEFAULT NULL,
  `lat` decimal(20,6) DEFAULT NULL,
  `status` int(1) DEFAULT NULL,
  `crid` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT;

--
-- Indexes for table `ui_ip`
--
ALTER TABLE `ui_ip`
  ADD PRIMARY KEY (`id`) USING BTREE,
  ADD KEY `state` (`state`) USING BTREE,
  ADD KEY `u_s_ip` (`u_s_ip`),
  ADD KEY `u_e_ip` (`u_e_ip`);
--
-- AUTO_INCREMENT for table `ui_ip`
--
ALTER TABLE `ui_ip`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;

PHP实现IP地址查询MYSQL对应的地理位置代码:


function wztm_mysql_get($sqlstr)
{
$rsql = mysql_query($sqlstr);
$infolist = array();
$i=0;
if($rsql)
{
while($row = mysql_fetch_assoc($rsql)) 
{ 
$infolist[$i]=$row;
$i++;
}
} 
return $infolist;
}
function ecs_geoip($ip)
{
  $ip_temp=explode(".",$ip);
  $ip_num=$ip_temp[0]*256*256*256+$ip_temp[1]*256*256+$ip_temp[2]*256+$ip_temp[2];
  $get_ip=wztm_mysql_get("select a1,a2,a3,a4,a5,a6 from ui_ip where u_s_ip
  if(count($get_ip)>0)
    $addinfo=$get_ip[0]['a1'].$get_ip[0]['a2'].$get_ip[0]['a3'].$get_ip[0]['a4']."(".$get_ip[0]['a6'].")";
  else
    $addinfo="未知";
  return $addinfo;
}
echo ecs_geoip("116.253.0.77");



php接Mysql数据库代码就省略了。

功能写好后,在批量调用时,出现了慢的问题,在百万级数据库查询一条记录4H4G的服务器配置大约0.8秒,但一个页面如果需要列20条记录,这样加载一次页面就需要约15秒左右,这样开发的产品是不能拿出来用的,所以还是得继续优化程序。

解决思路:

一、用户访问时就通过接口把IP地址转换成物理地址

这个方法马上给PASS掉,因为,每个流量访问都得去查询百万级数据库,反而更占硬件资源了。

二、在后台管理人员浏览数据时再进行转换

这个是在第一方法上优化出来的,读取数据时,先比对这个IP是否在流量统计表中已存在,已有就直接拉取流量统计表的数据更新本条内容,否则就去Ip地址库查询数据。

当然第二点也是有缺点,如果没有通过地址转换的记录就无法统计地址位置的信息。

三、通过定时转换功能指令达到转换

开发一个定时器,通过日志分析在基本无用户访问的时候,进行转换。

通过以上三个方法,基本已能实现IP地址转换成地址位置的功能,其中第一点是不推荐的,第二点和第三点可根据实际情况做选择。如果大家有更好开发实现方案,可以在评论区留言。

实现功能后的展示地址:

前端的统计页,添加在开发完成的英文站中  https://cs.wzjm.cn

后端登录网址:https://cs.wzjm.cn/as_admin/logo.php

用户名:tj   密码:123456

以上信息复制在电脑端即可查看

最后,附上IP地址Mysql数据库下载地址,因为有几百M,我就放到自己的百度网盘了,需要的可以关注本公众号后回复 "ip地址"即可获得。

image.png

我来说两句(0)
:zui: :wink: :twisted: :roll: :oops: :mrgreen: :love: :lol: :jidong: :idea: :han:
发表评论(Ctrl+Enter)
—— 金马科技公众号 ——
十二年 行业积累

砥砺前行路上,有您关注,相聚相研共话成长!

如有意向,请与我们联系

办公电话:0774-3838278 / QQ:154727262 / 微信:wztmma