微信公众平台开发(五) 天气预报功能开发


Posted in PHP onDecember 03, 2016

一、简介

前面几篇文章对微信公众平台的开通及简单使用做了简单的介绍,但都没有涉及到实际使用中的问题,例如天气查询,公交查询,快递查询等。接下来的几篇文章将对实际生活中会经常使用到的一些功能进行开发讲解,以供读者参考。

这一篇文章将对大家每天都会关心的天气查询进行开发,例如,用户发送消息 “苏州天气”,则会返回苏州实时天气状况,以及未来两天甚至未来五天的天气状况。

二、思路分析

首先要对用户发送过来的消息进行判断,判断消息里是否含有“天气”关键字,如果含有,则需要继续提取地区信息,然后再通过中国天气网(http://www.weather.com.cn)提供的开放API进行相关地区天气查询。

三、关键字判断与地区读取

用户发送过来查询天气的消息的格式是固定好的,即 “地区+天气”,所以首先截取后两个字,判断是否为 “天气” 关键字。

使用php函数 mb_substr() 截取,关于该函数的用法:

mb_substr — 获取字符串的部分

 string mb_substr ( string $str , int $start [, int $length [, string $encoding ]] )

说明:根据字符数执行一个多字节安全的 substr() 操作。 位置是从 str 的开始位置进行计数。 第一个字符的位置是 0。第二个字符的位置是 1,以此类推。

参数:

str

从该 string 中提取子字符串。

start

str 中要使用的第一个字符的位置。

正数 -> 从字符串开头指定位置开始;

负数 -> 从字符串结尾指定位置开始;

length

str 中要使用的最大字符数。

正数 -> 从 start 处开始最多包括 length 个字符;

负数 -> string 末尾处的 length 个字符将会被漏掉(若 start 是负数则从字符串开头算起)。

encoding

encoding 参数为字符编码。如果省略,则使用内部字符编码。

返回值:

mb_substr() 函数根据 start 和 length 参数返回 str 中指定的部分。

$str = mb_substr($keyword,-2,2,"UTF-8");

从消息的结尾数第二个字符开始截取,截取两个字符,然后加以判断是否为 “天气” 关键字。

下面进行地区提取,还是使用 mb_substr() 函数。

$str_key = mb_substr($keyword,0,-2,"UTF-8");

从消息的开头开始,截掉末尾的两个字符(天气),既得地区关键字。

然后进行判断,继而调用函数查询天气数据。

if($str == '天气' && !empty($str_key))
{
  //调用函数查询天气数据
}

四、调用 weather() 函数查询

我们这里调用的是中国国家气象局提供的天气预报API接口,接口地址:http://m.weather.com.cn/data/101190401.html

URL中的数字指代城市的编号101190401(苏州),其他城市对应关系将在下面提供。

该接口返回信息比较全面,也是以json格式提供,格式如下:

{"weatherinfo":{
//基本信息;
"city":"苏州","city_en":"suzhou",
"date_y":"2013年7月9日","date":"","week":"星期二","fchh":"18","cityid":"101190401",
//摄氏温度
"temp1":"30℃~37℃",
"temp2":"30℃~37℃",
"temp3":"29℃~35℃",
"temp4":"27℃~33℃",
"temp5":"27℃~31℃",
"temp6":"27℃~35℃",
//华氏温度;
"tempF1":"86?~98.6?",
"tempF2":"86?~98.6?",
"tempF3":"84.2?~95?",
"tempF4":"80.6?~91.4?",
"tempF5":"80.6?~87.8?",
"tempF6":"80.6?~95?",
//天气描述;
"weather1":"晴转多云",
"weather2":"晴转多云",
"weather3":"晴转多云",
"weather4":"多云",
"weather5":"雷阵雨转中雨",
"weather6":"雷阵雨转多云",
//天气描述图片序号
"img1":"0",
"img2":"1",
"img3":"0",
"img4":"1",
"img5":"0",
"img6":"1",
"img7":"1",
"img8":"99",
"img9":"4",
"img10":"8",
"img11":"4",
"img12":"1",
//图片名称;
"img_single":"1",
"img_title1":"晴",
"img_title2":"多云",
"img_title3":"晴",
"img_title4":"多云",
"img_title5":"晴",
"img_title6":"多云",
"img_title7":"多云",
"img_title8":"多云",
"img_title9":"雷阵雨",
"img_title10":"中雨",
"img_title11":"雷阵雨",
"img_title12":"多云",
"img_title_single":"多云",
//风速描述
"wind1":"西南风3-4级",
"wind2":"西南风3-4级",
"wind3":"东南风3-4级",
"wind4":"东南风3-4级转4-5级",
"wind5":"东南风4-5级转西南风3-4级",
"wind6":"西南风3-4级转4-5级",
//风速级别描述
"fx1":"西南风",
"fx2":"西南风",
"fl1":"3-4级",
"fl2":"3-4级",
"fl3":"3-4级",
"fl4":"3-4级转4-5级",
"fl5":"4-5级转3-4级",
"fl6":"3-4级转4-5级",
//今日穿衣指数;
"index":"炎热",
"index_d":"天气炎热,建议着短衫、短裙、短裤、薄型T恤衫等清凉夏季服装。",
//48小时穿衣指数
"index48":"炎热",
"index48_d":"天气炎热,建议着短衫、短裙、短裤、薄型T恤衫等清凉夏季服装。",
//紫外线及48小时紫外线
"index_uv":"中等",
"index48_uv":"中等",
//洗车指数
"index_xc":"适宜",
//旅游指数
"index_tr":"较不宜",
//舒适指数
"index_co":"很不舒适",
"st1":"36",
"st2":"28",
"st3":"36",
"st4":"28",
"st5":"34",
"st6":"27",
//晨练指数
"index_cl":"较适宜",
//晾晒指数
"index_ls":"适宜",
//过敏指数
"index_ag":"不易发"}}

我们可以通过解析JSON,获取相应城市的天气数据。

weather() 函数如下:

private function weather($n){
 include("weather_cityId.php");
 $c_name=$weather_cityId[$n];
 if(!empty($c_name)){
  $json=file_get_contents("http://m.weather.com.cn/data/".$c_name.".html");
  return json_decode($json);
 } else {
  return null;
 }
}

这里include 了一个城市对应关系文件 weather_cityId.php,格式如下:

<?php
$weather_cityId = array("北京"=>"101010100","上海"=>"101020100","苏州"=>"101190401");
?>

根据传入的城市名,得到城市代码,如果不为空,则调用中国天气网的API进行查询,返回json格式的数据,然后进行解析并返回数据,如果为空,则返回null值。

五、组织回复消息形式

判断返回数据是否为空,若为空,则 $contentStr = "抱歉,没有查到\"".$str_key."\"的天气信息!";

若返回数据不为空,则:

$contentStr = "【".$data->weatherinfo->city."天气预报】\n".$data->weatherinfo->date_y." ".$data->weatherinfo->fchh."时发布"."\n\n实时天气\n".$data->weatherinfo->weather1." ".$data->weatherinfo->temp1." ".$data->weatherinfo->wind1."\n\n温馨提示:".$data->weatherinfo->index_d."\n\n明天\n".$data->weatherinfo->weather2." ".$data->weatherinfo->temp2." ".$data->weatherinfo->wind2."\n\n后天\n".$data->weatherinfo->weather3." ".$data->weatherinfo->temp3." ".$data->weatherinfo->wind3;

说明:

$data->weatherinfo->city

//获取城市名,这里为苏州

$data->weatherinfo->date_y

//获取日期,这里为2013年7月9日

$data->weatherinfo->fchh

//数据发布时间

$data->weatherinfo->weather1

//实时天气

$data->weatherinfo->temp1

//实时温度

$data->weatherinfo->wind1

//实时风向和风速

$data->weatherinfo->index_d

//穿衣指数

weather2, temp2, wind2 分别代表了明天的天气,温度和风向风速,其他的以此类推。

\n

//表示换行

六、测试

微信公众平台开发(五) 天气预报功能开发

七、完整代码

<?php
/**
 * wechat php test
 */

//define your token
define("TOKEN", "zhuojin");
$wechatObj = new wechatCallbackapiTest();
$wechatObj->responseMsg();
//$wechatObj->valid();

class wechatCallbackapiTest
{
 /*public function valid()
 {
  $echoStr = $_GET["echostr"];

  //valid signature , option
  if($this->checkSignature()){
   echo $echoStr;
   exit;
  }
 }*/

 public function responseMsg()
 {
  //get post data, May be due to the different environments
  $postStr = $GLOBALS["HTTP_RAW_POST_DATA"];

   //extract post data
  if (!empty($postStr)){
    
     $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
    $RX_TYPE = trim($postObj->MsgType);

    switch($RX_TYPE)
    {
     case "text":
      $resultStr = $this->handleText($postObj);
      break;
     case "event":
      $resultStr = $this->handleEvent($postObj);
      break;
     default:
      $resultStr = "Unknow msg type: ".$RX_TYPE;
      break;
    }
    echo $resultStr;
  }else {
   echo "";
   exit;
  }
 }

 public function handleText($postObj)
 {
  $fromUsername = $postObj->FromUserName;
  $toUsername = $postObj->ToUserName;
  $keyword = trim($postObj->Content);
  $time = time();
  $textTpl = "<xml>
     <ToUserName><![CDATA[%s]]></ToUserName>
     <FromUserName><![CDATA[%s]]></FromUserName>
     <CreateTime>%s</CreateTime>
     <MsgType><![CDATA[%s]]></MsgType>
     <Content><![CDATA[%s]]></Content>
     <FuncFlag>0</FuncFlag>
     </xml>";    
  if(!empty( $keyword ))
  {
   $msgType = "text";

   //天气
   $str = mb_substr($keyword,-2,2,"UTF-8");
   $str_key = mb_substr($keyword,0,-2,"UTF-8");
   if($str == '天气' && !empty($str_key)){
    $data = $this->weather($str_key);
    if(empty($data->weatherinfo)){
     $contentStr = "抱歉,没有查到\"".$str_key."\"的天气信息!";
    } else {
     $contentStr = "【".$data->weatherinfo->city."天气预报】\n".$data->weatherinfo->date_y." ".$data->weatherinfo->fchh."时发布"."\n\n实时天气\n".$data->weatherinfo->weather1." ".$data->weatherinfo->temp1." ".$data->weatherinfo->wind1."\n\n温馨提示:".$data->weatherinfo->index_d."\n\n明天\n".$data->weatherinfo->weather2." ".$data->weatherinfo->temp2." ".$data->weatherinfo->wind2."\n\n后天\n".$data->weatherinfo->weather3." ".$data->weatherinfo->temp3." ".$data->weatherinfo->wind3;
    }
   } else {
    $contentStr = "感谢您关注【卓锦苏州】"."\n"."微信号:zhuojinsz"."\n"."卓越锦绣,名城苏州,我们为您提供苏州本地生活指南,苏州相关信息查询,做最好的苏州微信平台。"."\n"."目前平台功能如下:"."\n"."【1】 查天气,如输入:苏州天气"."\n"."【2】 查公交,如输入:苏州公交178"."\n"."【3】 翻译,如输入:翻译I love you"."\n"."【4】 苏州信息查询,如输入:苏州观前街"."\n"."更多内容,敬请期待...";
   }
   $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);
   echo $resultStr;
  }else{
   echo "Input something...";
  }
 }

 public function handleEvent($object)
 {
  $contentStr = "";
  switch ($object->Event)
  {
   case "subscribe":
    $contentStr = "感谢您关注【卓锦苏州】"."\n"."微信号:zhuojinsz"."\n"."卓越锦绣,名城苏州,我们为您提供苏州本地生活指南,苏州相关信息查询,做最好的苏州微信平台。"."\n"."目前平台功能如下:"."\n"."【1】 查天气,如输入:苏州天气"."\n"."【2】 查公交,如输入:苏州公交178"."\n"."【3】 翻译,如输入:翻译I love you"."\n"."【4】 苏州信息查询,如输入:苏州观前街"."\n"."更多内容,敬请期待...";
    break;
   default :
    $contentStr = "Unknow Event: ".$object->Event;
    break;
  }
  $resultStr = $this->responseText($object, $contentStr);
  return $resultStr;
 }
 
 public function responseText($object, $content, $flag=0)
 {
  $textTpl = "<xml>
     <ToUserName><![CDATA[%s]]></ToUserName>
     <FromUserName><![CDATA[%s]]></FromUserName>
     <CreateTime>%s</CreateTime>
     <MsgType><![CDATA[text]]></MsgType>
     <Content><![CDATA[%s]]></Content>
     <FuncFlag>%d</FuncFlag>
     </xml>";
  $resultStr = sprintf($textTpl, $object->FromUserName, $object->ToUserName, time(), $content, $flag);
  return $resultStr;
 }

 private function weather($n){
  include("weather_cityId.php");
  $c_name=$weather_cityId[$n];
  if(!empty($c_name)){
   $json=file_get_contents("http://m.weather.com.cn/data/".$c_name.".html");
   return json_decode($json);
  } else {
   return null;
  }
 }

 private function checkSignature()
 {
  $signature = $_GET["signature"];
  $timestamp = $_GET["timestamp"];
  $nonce = $_GET["nonce"]; 
    
  $token = TOKEN;
  $tmpArr = array($token, $timestamp, $nonce);
  sort($tmpArr);
  $tmpStr = implode( $tmpArr );
  $tmpStr = sha1( $tmpStr );
  
  if( $tmpStr == $signature ){
   return true;
  }else{
   return false;
  }
 }
}

?>

关于城市对应关系文件 weather_cityId.php,目前更新到了2564个城市,以后还会继续增加,请到官方网盘http://pan.baidu.com/s/1gfcBX6N下载吧。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

PHP 相关文章推荐
实现“上一页”和“下一页按钮
Oct 09 PHP
PHP中文件缓存转内存缓存的方法
Dec 06 PHP
php中http_build_query 的一个问题
Mar 25 PHP
关于二级目录拖拽排序的实现(源码示例下载)
Apr 26 PHP
PHP中VC6、VC9、TS、NTS版本的区别与用法详解
Oct 26 PHP
IIS下PHP的三种配置方式对比
Nov 20 PHP
php中动态变量用法实例
Jun 10 PHP
PHP实现简单汉字验证码
Jul 28 PHP
PHP 7安装调试工具Xdebug扩展的方法教程
Jun 17 PHP
PHP ADODB实现分页功能简单示例
May 25 PHP
thinkPHP5框架接口写法简单示例
Aug 05 PHP
Laravel5.1 框架控制器基础用法实例分析
Jan 04 PHP
php die()与exit()的区别实例详解
Dec 03 #PHP
详解Yii2 rules 的验证规则
Dec 02 #PHP
Yii框架数据模型的验证规则rules()被执行的方法
Dec 02 #PHP
thinkPHP统计排行与分页显示功能示例
Dec 02 #PHP
thinkPHP交易详情查询功能详解
Dec 02 #PHP
php变量与数组相互转换的方法(extract与compact)
Dec 02 #PHP
php图像处理函数imagecopyresampled用法详解
Dec 02 #PHP
You might like
很温暖很温暖的Lester Young
2021/03/03 冲泡冲煮
php ss7.5的数据调用 (笔记)
2010/03/08 PHP
Trying to clone an uncloneable object of class Imagic的解决方法
2012/01/11 PHP
四种php中webservice实现的简单架构方法及实例
2015/02/03 PHP
PHP中的类型约束介绍
2015/05/11 PHP
PHP call_user_func和call_user_func_array函数的简单理解与应用分析
2019/11/25 PHP
游戏人文件夹程序 ver 4.03
2006/07/14 Javascript
js向上无缝滚动,网站公告效果 具体代码
2013/11/18 Javascript
无闪烁更新网页内容JS实现
2013/12/19 Javascript
extjs 分页使用jsp传递数据示例
2014/07/29 Javascript
javascript数组去重的六种方法汇总
2015/08/16 Javascript
JavaScript操作class和style样式代码详解
2016/02/13 Javascript
jquery实现图片上传前本地预览功能
2016/05/10 Javascript
Bootstrap 最常用的JS插件系列总结(图片轮播、标签切换等)
2016/07/14 Javascript
js接收并转化Java中的数组对象的方法
2016/08/11 Javascript
详解JavaScript中的属性和特性
2016/12/08 Javascript
使用validate.js实现表单数据提交前的验证方法
2018/09/04 Javascript
vue中选项卡点击切换且能滑动切换功能的实现代码
2018/11/25 Javascript
详解JQuery基础动画操作
2019/04/12 jQuery
在Vue环境下利用worker运行interval计时器的步骤
2019/08/01 Javascript
javascript实现贪吃蛇小游戏
2020/07/28 Javascript
[01:01:04]2018DOTA2亚洲邀请赛 4.5 淘汰赛 OpTic vs TNC 第一场
2018/04/06 DOTA
Python使用装饰器进行django开发实例代码
2018/02/06 Python
python 检查是否为中文字符串的方法
2018/12/28 Python
Python使用matplotlib 画矩形的三种方式分析
2019/10/31 Python
Python中的整除和取模实例
2020/06/03 Python
css3 中实现炫酷的loading效果
2019/04/26 HTML / CSS
LACOSTE波兰官网:Polo衫、服装和鞋类
2020/09/29 全球购物
运动会广播稿80字
2014/01/23 职场文书
美丽乡村建设实施方案
2014/03/23 职场文书
《天安门广场》教学反思
2014/04/23 职场文书
个人考核材料
2014/05/15 职场文书
2015年七一建党节活动总结
2015/03/20 职场文书
小鞋子观后感
2015/06/05 职场文书
无犯罪记录证明样本
2015/06/16 职场文书
Mysql多层子查询示例代码(收藏夹案例)
2022/03/31 MySQL