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

一、简介

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

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

二、思路分析

首先要对用户发送过来的消息进行判断,判断消息里是否含有“天气”关键字,如果含有,则需要继续提取地区信息,然后再通过中国天气网(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下载吧。

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

(0)

相关推荐

  • 使用正则表达式替换报表名称中的特殊字符(推荐)

    正则表达式,又称规则表达式.(英语:Regular Expression,在代码中常简写为regex.regexp或RE),计算机科学的一个概念.正则表通常被用来检索.替换那些符合某个模式(规则)的文本. 许多程序设计语言都支持利用正则表达式进行字符串操作.例如,在Perl中就内建了一个功能强大的正则表达式引擎,还有java语言自带的.正则表达式这个概念最初是由Unix中的工具软件(例如sed和grep)普及开的.正则表达式通常缩写成"regex",单数有regexp.regex,复数

  • 原生js实现查询天气小应用

    本文实例为大家分享了js查询天气应用,供大家参考,具体内容如下 demo:  https://zsqosos.github.io/weather/ 实现功能:打开网页时显示用户所在城市的天气状况,在输入框输入城市可查询其它城市. 实现过程:先调用百度地图的API来获取用户所在的城市,随后调用聚合数据的天气API将数据放在页面上.由于ajax不支持跨域,所以采用了jsonp的方式来调用数据. 实现的原理比较简单,HTML和css比较长,我就只将js代码贴出来,想看完整代码的朋友可以去我的githu

  • Jquery获取当前城市的天气信息

    本文实例为大家分享了Jquery获取当前城市的天气信息代码,供大家参考,具体内容如下 HTML代码: <div id="weather"></div> Jquery代码: function findWeather() { var cityUrl = 'http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=js'; $.getScript(cityUrl, function(script, textSt

  • 简单三步实现报表页面集成天气

    条条框框的报表页面枯燥乏味?不妨给页面加点"新意"! 前阵子,在看天气预报的时候,发现免费天气预报的调用代码,瞬间想到可以给我开发的报表"润润色". 一共三个步骤,教你手到擒来 第一步 先去天气资源提供者(自行百度)挑选适合自己页面的预报 第二步 copy框中iframe标签. JS代码: document.writeln("<iframe name=\"weather_inc\" src=\"http:\/\/i.ti

  • Java 调用天气Webservice详解及实例代码

    Java调用天气Webservice的小应用 废话不多说,直接贴代码: CityReq.java package com.weather; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement(name="getWeatherbyCityName",namespace="http://WebXml.com.cn/

  • 解决VS2015中没有报表项(ReportViewer)的方法

    没有报表,一般默认安装之后会出现这种情况,在安装的时候选择自定义安装,把Microsoft Office 开发人员工具.Microsoft SQL Server Data Tools勾选上,安装之后就可以找到了. 1.点击vs_entprise安装 2.安装过后的点击修改 3.额外勾选Microsoft Office 开发人员工具.Microsoft SQL Server Data Tools 两项.如下图 4.点击安装,等待安装之后就可以看到报表啦(因为我的有内容没有更新,所以显示的是更新,一

  • Java FineReport报表工具导出EXCEL的四种方式

    在实际的应用中会经常需要将数据导出成excel,导出的方式除原样导出还有分页导出.分页分sheet导出和大数据量导出.对于excel2003版,限制了每个sheet的最大行数和列数,大数据量导出时会默认时分多个sheet,而excel2007不会出现这样的问题.这些导出方式在JAVA程序中分别有不同的接口来实现: 1. 原样导出 原样导出就是不预览直接导出excel 其程序接口代码如下: outputStream = new FileOutputStream(new File("E:\\Exce

  • Web打印解决方案之普通报表打印功能

    做过很多的Web项目,大多数在打印页面内容的时候,采用的都是通过Javascript调用系统内置的打印方法进行打印,也就是调用PrintControl.ExecWB(?,?)实现直接打印和打印预览功能.打印的效果及控制性虽然不是很好,但是也能勉强使用,应付一般的打印还是可以的了. 代码如下所示: 代码 Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->

  • php微信开发之百度天气预报

    本文实例为大家分享了php微信百度天气预报的开发代码,供大家参考,具体内容如下 1.登录百度ak申请:http://lbsyun.baidu.com/apiconsole/key 2.实现天气信息功能 baiduWeather.php <?php /** * 使用百度天气预报接口获取城市天气信息案例实现 */ //获取城市天气信息 function getWeatherInfo($cityName){ if($cityName == "" || (strstr($cityName

  • 在ASP.NET 2.0中操作数据之十:使用 GridView和DetailView实现的主/从报表

    导言 在前面的教程我们看到了如何使用两个页面(一个主页,用于列出供应商; 一个明细页,用于显示选定供应商提供的产品)创建主/从报表 . 这种两个页面的报表格式也可以集中在一个页面上. 这篇教程将会使用一个GridView, 它的每一行都包含产品的名称和单价以及一个选择按钮. 单击一个产品的选择按钮会在同一页的DetailsView控件上显示该产品的全部详细信息. 图 1: 单击选择按钮显示产品明细 Step 1: 创建一个可选择行的GridView 回想一下前面的跨页的主/从报表, 它的每个主记

随机推荐