基于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讨论区的资料,再通过自己的实际测试而得来,属于自己原创的内容说实话很少,写这一篇是为了记录自己 ...
随机推荐
- Java IO:为什么InputStream只能读一次
http://zhangbo-peipei-163-com.iteye.com/blog/2021879 InputStream的接口规范就是这么设计的. /** * Reads the next b ...
- WCF 服务
1.代码 using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Seriali ...
- 导入pymysql模块出错:No module named 'pymysql'
前提: 使用的版本为:Python 3.6.4 pymysql已经被成功安装了,并通过命令行的方式验证已成功安装. 但在pycharm中运行工程时候时候报错:No module named 'pymy ...
- python学习笔记08-- socket编程
本节内容: 一.网络基础知识 二.socket概念及相关语法 2.1socket概念 2.2socket解释 2.3socket模块功能介绍 2.4socket粘包问题 2.5Socket多并发 一. ...
- Java连接Neo4j的两种方式
1.Neo4j数据库的两种方式 Neo4j可以以两种方式运行: Java应用程序中的嵌入式数据库 通过REST的独立服务器 不管哪一种方式,这个选择不会影响查询和使用数据库的方式. 它是由应用程序的性 ...
- Leetcode892.Surface Area of 3D Shapes三维形体的表面积
在 N * N 的网格上,我们放置一些 1 * 1 * 1 的立方体. 每个值 v = grid[i][j] 表示 v 个正方体叠放在单元格 (i, j) 上. 返回结果形体的总表面积. 示例 1: ...
- Xdebug步骤
谷歌浏览器安装xdebug cd /etc/php/7.2/fpm/conf.d 重启sudo service php7.1-fpm restart (注意 php版本) 重启编辑器
- golang的包导入import
import别名/点下划线(1)import关键字的作用:作用是导入该go源文件所依赖的package包.用在go源文件中,紧接在pakage后面的部分.(2)只要在源文件中用到了的package包就 ...
- ls command not found
编辑profile文件没有写正确,导致在命令行下 ls等命令不能够识别. 在命令行下打入下面这段就可以了 export PATH=/usr/local/sbin:/usr/local/bin:/sbi ...
- 深入浅出Cocoa之消息(二)-详解动态方法决议(Dynamic Method Resolution) 【转】
序言 如果我们在 Objective C 中向一个对象发送它无法处理的消息,会出现什么情况呢?根据前文<深入浅出Cocoa之消息>的介绍,我们知道发送消息是通过 objc_send(id, ...