基于thinkphp实现根据用户ip判断地理位置并提供对应天气信息的应用
https://blog.csdn.net/MyCodeDream/article/details/46706469
我们都知道,在很多的网站都提供了给用户提供天气预报的功能,有时会发现,用户即使不输入任何和自己有关的地理位置信息,同样的网站也可以去判断地理位置并且显示天气信息,我们可能会想到用ip去判断地理位置,的确是这样,但是,如果想自己一样完全的开发,确实有一点麻烦,所以这里简单的说一下这个应用的业务逻辑(以用户第一次打开页面为起点):
1:获取ip:ip按照我自己的说法有两种,一种是独立ip,真实存在,另一种是路由器分配的ip,这个当然不具有某种意义上的唯一性,这两种ip当然都要考虑,第一种非常容易或得,取$_SERVER内的元素值就可以,但问题是第二种,像192.168.1.1这样的是无法判断的,那么就没法处理或得用户的位置信息,这里本来采用curl的扩展来抓取的,但是这个扩展说什么就是无法使用,所以这种情况先放在一边,仅考虑用户使用独立ip访问的情况。
这里补充一下,server的参数不是server_addr而是REMOTE_ADDR,只有这样才能取到用户的真是地址,这样的话就不用麻烦的取另外处理
2:当我们获取ip之后就应该根据ip地址库去查找用户的ip所在地,这里有两个地方需要注意,1:ip地址库必须为utf-8编码,2:或得的信息是一个完整的地址信息,而后面需要城市名称局可以,所以,要做一下字符串的截取,或得简化城市地址。
3:当或得了用户的地址显然还是不行,想想,最终于天气接口对接获取数据的是城市代码,这两个还是要转化一下,这里我采用了暴力的办法遍历城市代码库或得该城市的代码。
4:获取到城市的代码之后,就要去连接数据接口获取数据,这个数据时json数据,需要json_encode()转码,我这里或得的是一个对象,有的接口不一样,具体情况具体分析,然后,最重要的就是分配这些数据,说是这些,其实就是这个对象,后来发现没有逐个分配是正确的,这样有利于代码的移植。
5:在视图去调用模板分配的数据,相信这个都会。
6:其实上面的步骤已经把第一次打开页面的整个业务逻辑给处理完了,还有一个就是我在视图给用户提供了输入城市名查询城市天气的功能,这样按顺序的分析一下,正常的获取用户的输入信息就是城市名
7:这里就已经或得了城市名,直接参与获取城市代码的遍历就可以了,这里有个非常重要的逻辑问题就是先后顺序和如何判断才能够把这两个功能很好的结合在一块,一定是:
先判断是否系统自动获取城市名称是否为空,如果不为空只城市名就是或得的名字,反之,就提示ip地址没有查询到对应地址信息,紧接着,注意一定是紧接着下面,是顺序结构,判断用户的输入是否为空,如果不为空,那么就让城市名为用户输入,总而言之就是用户的输入权限一定要大于系统自动获取的权限,这样就可以完整的把两个代码结合在一起,另外,我是把获取ip和取出城市名分别做成了两个方法。
上面写的比较乱,这样的话,下面是我的部分实例代码,因安全版权各方面原因,数据接口我做了处理不可以使用,仅提供方法参考,粘贴无用,自主研究。
视图weather_test.html:
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
- <html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=">
- <title>天气预报</title>
- <style type="text/css">
- *{
- margin: 0px;
- padding: 0px;
- }
- </style>
- </head>
- <body>
- <br>
- <form action="{$smarty_const.__SELF__}" method="post">
- <input type="text" name="cityname">
- <input type="submit" value="更换城市"/>
- </form>
- <table border="1px" style="margin-top: 20px;margin-left: 20px;">
- <tr><td colspan="2">即时天气信息</td></tr>
- <tr style="border-spacing: 0px; padding: 0px;">
- <td style="border-spacing: 0px; padding: 0px;">城市</td>
- <td>{$all_info->forecast->city}</td>
- </tr>
- <tr>
- <td>基本天气</td>
- <td>{$all_info->realtime->weather}</td>
- </tr>
- <tr>
- <td>温度</td>
- <td>{$all_info->realtime->temp}</td>
- </tr>
- <tr>
- <td>风向</td>
- <td>{$all_info->realtime->WD}</td>
- </tr>
- <tr>
- <td>更新时间</td>
- <td>{$all_info->realtime->time}</td>
- </tr>
- </table>
- <table border="1px" style="margin-top: 20px;margin-left: 20px;">
- <tr><td colspan="2">生活建议</td></tr>
- <tr style="border-spacing: 0px; padding: 0px;">
- <td style="border-spacing: 0px; padding: 0px;">城市</td>
- <td>{$all_info->forecast->city}</td>
- </tr>
- <tr>
- <td>防嗮建议</td>
- <td>{$all_info->index[0]->details}</td>
- </tr>
- <tr>
- <td>穿衣建议</td>
- <td>{$all_info->index[1]->details}</td>
- </tr>
- <tr>
- <td>运动建议</td>
- <td>{$all_info->index[2]->details}</td>
- </tr>
- <tr>
- <td>洗车建议</td>
- <td>{$all_info->index[3]->details}</td>
- </tr>
- <tr>
- <td>晾晒建议</td>
- <td>{$all_info->index[4]->details}</td>
- </tr>
- <tr>
- <td>更新时间</td>
- <td>{$all_info->realtime->time}</td>
- </tr>
- </table>
- <table border="1px" style="margin-top: 20px;margin-left: 20px;">
- <tr><td colspan="5">未来四天天气信息 城市: {$all_info->forecast->city}</tr>
- <tr style="border-spacing: 0px; padding: 0px;">
- <td>项目/日期</td>
- <td>今天</td>
- <td>明天</td>
- <td>后天</td>
- <td>大后天</td>
- </tr>
- <tr>
- <td>概况</td>
- <td>{$all_info->forecast->weather1}</td>
- <td>{$all_info->forecast->weather2}</td>
- <td>{$all_info->forecast->weather3}</td>
- <td>{$all_info->forecast->weather4}</td>
- </tr>
- <tr>
- <td>温度</td>
- <td>{$all_info->forecast->temp1}</td>
- <td>{$all_info->forecast->temp2}</td>
- <td>{$all_info->forecast->temp3}</td>
- <td>{$all_info->forecast->temp4}</td>
- </tr>
- <tr>
- <td>风向</td>
- <td>{$all_info->forecast->wind1}</td>
- <td>{$all_info->forecast->wind2}</td>
- <td>{$all_info->forecast->wind3}</td>
- <td>{$all_info->forecast->wind4}</td>
- </tr>
- <tr>
- <td>风力</td>
- <td>{$all_info->forecast->fl1}</td>
- <td>{$all_info->forecast->fl2}</td>
- <td>{$all_info->forecast->fl3}</td>
- <td>{$all_info->forecast->fl4}</td>
- </tr>
- </table>
- <table border="1px" style="margin-top: 20px;margin-left: 20px;">
- <tr><td colspan="2">今日空气质量状况</td></tr>
- <tr style="border-spacing: 0px; padding: 0px;">
- <td style="border-spacing: 0px; padding: 0px;">城市</td>
- <td>{$all_info->forecast->city}</td>
- </tr>
- <tr>
- <td>PM2.5</td>
- <td>{$all_info->aqi->pm25}</td>
- </tr>
- <tr>
- <td>PM10</td>
- <td>{$all_info->aqi->pm10}</td>
- </tr>
- <tr>
- <td>SO2</td>
- <td>{$all_info->aqi->so2}</td>
- </tr>
- <tr>
- <td>NO2</td>
- <td>{$all_info->aqi->no2}</td>
- </tr>
- <tr>
- <td>更新时间</td>
- <td>{$all_info->aqi->pub_time}</td>
- </tr>
- </table>
- </body>
- </html>
类方法:
- public function weather_test(){
- require_once './Component/Citycode.php';
- //////这里是根据客户端的ip判断地理位置
- //定义两个标志变量
- $count=0;
- $city_id='101120301';//默认大淄博
- $city_name_cin=$_POST['cityname'];
- $city_sim_name=R('Test/get_user_cityname');
- //这是系统根据ip自动判断的位置
- echo $city_sim_name;
- if($city_sim_name!=null){
- $city_name_cin=$city_sim_name;
- }
- //这是用户输入的位置
- if(!empty($_POST['cityname'])){
- //放置信息覆盖
- $city_name_cin=$_POST['cityname'];
- }
- ////////不管是ip定位还是用户输入最终需要遍历获取城市代码的变量只要$city_name_cin
- foreach ($citycode as $key => $value){
- if($key==$city_name_cin){
- $city_id=$citycode[$city_name_cin];
- $count++;
- }
- }
- if($count==0){
- echo "对不起,您输入的地址没有找到!默认淄博哦";
- }else{
- echo $city_name_cin."的天气信息如下";
- }
- //接口已经处理,请勿使用,仅供学习
- $weather_interface_url="http://weatherai.markt.xiaomi.com/wtr-v2/weather?cityId=".$city_id."&mei=e32c88633283737f5d9f381d47&device=HM2013023&miuiVersion=JHBCNBD16.0&modDevice=ce=miuiWeatherAp";
- $all_weather_info = json_decode(file_get_contents($weather_interface_url));
- //分配数据
- $this->assign("all_info",$all_weather_info);
- $this->display();
- }
- ///////////////////////////////////////////////////
- /*
- * 下面两个分别是获取主机ip和ip所在地的两个
- * 方法,最后的结果数值通过R方法,返回获取
- */
- //方法1:获取用户ip
- public function get_user_ip(){
- //先通过这种简单的方法获取主机的ip,通过R方法获取
- $host_ip=$_SERVER['SERVER_ADDR'];
- return $host_ip;
- }
- //方法2:获取地名
- public function get_user_cityname(){
- //得到用户的ip
- $host_ip=R('Test/get_user_ip');
- //这里ip地址库必须这样实例化
- $Ip = new \Org\Net\IpLocation('UTFWry.dat'); // 实例化类 参数表示IP地址库文件
- //可以同时放ip和域名
- $area = $Ip->getlocation($host_ip); // 获取域名服务器所在的位置
- $city_allname=$area['country'];
- $sim_cityname=explode("市",explode("省", $city_allname)[1])[0];
- return $sim_cityname;
- }
基于thinkphp实现根据用户ip判断地理位置并提供对应天气信息的应用的更多相关文章
- PHP实例:获取操作系统、IP、地理位置、浏览器、等信息
获取访客操作系统以及浏览器语言 <?php function GetBrowser(){ if(!empty($_SERVER['HTTP_USER_AGENT'])){ $br = $_SER ...
- 一个基于thinkphp的微信授权登陆功能
共享一份基于thinkphp开发的用户授权登陆的功能代码,本实例使用thinkphp的第三方微信公众平台PHP-SDK,地址https://github.com/dodgepudding/wechat ...
- 用户Ip地址和百度地图api接口获取用户地理位置(经纬度坐标,城市)
<?php //获取用户ip(外网ip 服务器上可以获取用户外网Ip 本机ip地址只能获取127.0.0.1) function getip(){ if(!empty($_SERVE ...
- PHP通过IP 获取 地理位置(实例)
发布:JB02 来源:脚本学堂 分享一例php代码,实现通过IP地址获取访问者的地理位置,在php编程中经常用到,有需要的朋友参考下吧.本节内容:PHP通过IP获取地理位置 例子: 复制代码代码 ...
- PHP通过IP 获取 地理位置(实例代码)
发布:JB02 来源:脚本学堂 分享一例php代码,实现通过IP地址获取访问者的地理位置,在php编程中经常用到,有需要的朋友参考下吧.本节内容:PHP通过IP获取地理位置 例子: 复制代码代码示 ...
- [项目回顾]基于Redis的在线用户列表解决方案
迁移:基于Redis的在线用户列表解决方案 前言: 由于项目需求,需要在集群环境下实现在线用户列表的功能,并依靠在线列表实现用户单一登陆(同一账户只能一处登陆)功能: 在单机环境下,在线列表的实现方案 ...
- 记一次企业级爬虫系统升级改造(六):基于Redis实现免费的IP代理池
前言: 首先表示抱歉,春节后一直较忙,未及时更新该系列文章. 近期,由于监控的站源越来越多,就偶有站源做了反爬机制,造成我们的SupportYun系统小爬虫服务时常被封IP,不能进行数据采集. 这时候 ...
- IP判断
题目描述 在基于Internet的程序中,我们常常需要判断一个IP字符串的合法性. 合法的IP是这样的形式: A.B.C.D 其中A.B.C.D均为位于[0, 255]中的整数.为了简单起见,我们规定 ...
- C# 获取用户IP地址(转载)
[ASP.NET开发]获取客户端IP地址 via C# 说明:本文中的内容是我综合博客园上的博文和MSDN讨论区的资料,再通过自己的实际测试而得来,属于自己原创的内容说实话很少,写这一篇是为了记录自己 ...
随机推荐
- git之操作准则
每天下班前合一次代码,每次合代码先pull 不要多人同时修改同一个文件,避免冲突 在每个人自己的分支进行开发,先合并到dev分支解决冲突,确认无冲突后再合并到master
- [洛谷P4141] 消失之物「背包DP」
暴力:暴力枚举少了哪个,下面套一个01背包 f[i][j]表示到了i物品,用了j容量的背包时的方案数,f[i][j]=f[i-1][j]+f[i-1][j-w[i]]O(n^3) 优化:不考虑消失的, ...
- .Net Core 授权系统组件解析
前面关于.Net Core如何进行用户认证的核心流程介绍完毕之后,.Net Core 认证系统之Cookie认证源码解析远程认证暂时不介绍,后期有时间,我会加上.接下去介绍认证组件是如何和认证组件一起 ...
- SpringBoot 使用 @Value 从 YAML文件读取属性
在 YAML中有如下配置 paypal: mode:live 在类中,通过 @Value属性读取 @Value("${paypal.mode}") private String m ...
- window10下载安装jieba
下载安装jieba的过程如下: 1 下载jieba 2 将其解压到E:\python2,如图所示: 3 在桌面左下角搜索框中输入"运行",之后输入"cmd".再 ...
- thinkphp---display与fetch区别
区别: ① display方法直接输出模板文件渲染后的内容,fetch方法是返回模板文件渲染后的内容 ② 有时候我们不想直接输出模板内容,而是希望对内容再进行一些处理后输出, 就可以使用fetch方法 ...
- 类似淘宝五星点评 ,Jquery实现代码
<!--默认五星,根据鼠标点击判断--> <!DOCTYPE html><html lang="en"><head> <met ...
- could not insert: [com.trs.om.bean.UserLog] The user specified as a definer ('root'@'127.0.0.1') does not exist
2019-07-01 11:24:09,315 [http-8080-24] org.hibernate.util.JDBCExceptionReporter logExceptionsWARN: S ...
- sublime配置node开发环境
下载node插件 https://github.com/tanepiper/SublimeText-Nodejs 下载zip压缩包后解压,文件名改为Node 打开文件“Nodejs.sublime-s ...
- 洛谷 P3258 [JLOI2014]松鼠的新家 树链剖分+差分前缀和优化
目录 题面 题目链接 题目描述 输入输出格式 输入格式 输出格式 输入输出样例 输入样例: 输出样例: 说明 说明 思路 AC代码 优化 优化后AC代码 总结 题面 题目链接 P3258 [JLOI2 ...