微信公众号开发之天气应用

20151228更新:百度API对天气信息的返回结果做了改变,指数信息需要重新解析,原有的代码公众号调用时已经无法正常显示指数信息。

20151230更新:28号是百度API升级造成的短暂故障,现已恢复正常,代码不需要更改。

本天气应用,通过发送城市名或位置获取天气信息,利用百度SDK

百度Key申请:http://lbsyun.baidu.com/apiconsole/key

通过上一个链接申请到AK和SK,也可以只申请AK不申请SK,申请了SK的需要计算SN

接口的形式如:http://api.map.baidu.com/telematics/v3/weather?location=北京&output=json&ak=yourkey

申请了SK的接口形式如:http://api.map.baidu.com/telematics/v3/weather?location=北京&output=json&ak=yourkey&sn=yoursn

接口说明:http://developer.baidu.com/map/carapi-7.htm

SN生成算法:http://developer.baidu.com/map/lbs-appendix.htm#.appendix1

其中location=后面接城市名或经纬度,但是跟微信获取到的顺序刚好相反,location=($object->Location_Y,$object->Location_X)

Weather类文件Weather.php

[php] view plain copy
  1. <?php  
  2.   
  3. class Weather  
  4. {  
  5.     var $ak = ‘AK‘;  
  6.     var $sk = ‘SK‘;  
  7.     var $url = ‘http://api.map.baidu.com/telematics/v3/weather?location=%s&output=%s&ak=%s&sn=%s‘;  
  8.     var $uri = ‘/telematics/v3/weather‘;  
  9.   
  10.     //计算sn  
  11.     function caculateAKSN($ak, $sk, $url, $querystring_arrays, $method = ‘GET‘)  
  12.     {  
  13.         if ($method === ‘POST‘){  
  14.             ksort($querystring_arrays);  
  15.         }  
  16.         $querystring = http_build_query($querystring_arrays);  
  17.         return md5(urlencode($url.‘?‘.$querystring.$sk));  
  18.     }  
  19.   
  20.     //$location可填地名或经纬度,$output可填json或xml  
  21.     //locationToWeatherResult(‘长沙‘);  
  22.     //locationToWeatherResult(‘121.67397,38.793570‘);  
  23.     public function locationToWeatherResult($location,$output=‘json‘){  
  24.         //当前为GBK编码时需要转换  
  25.         //$location = iconv(‘GB2312‘,‘UTF-8‘,$location);  
  26.   
  27.         //构造请求串数组  
  28.         $querystring_arrays = array (  
  29.             ‘location‘ => $location,  
  30.             ‘output‘ => $output,  
  31.             ‘ak‘ => $this->ak  
  32.         );  
  33.   
  34.         //调用sn计算函数,默认get请求  
  35.         $sn = $this->caculateAKSN($this->ak, $this->sk, $this->uri, $querystring_arrays);  
  36.         $target = sprintf($this->url, urlencode($location), $output, $this->ak, $sn);  
  37.   
  38.         $content = file_get_contents($target);  
  39.         return $content;  
  40.     }  
  41. }  
  42. ?>  


微信主页php页面

[php] view plain copy
  1. <?php  
  2. define("TOKEN", "token");  
  3.   
  4. $wechatObj = new wechatCallbackapiTest();  
  5. if (!isset($_GET[‘echostr‘])) {  
  6.     $wechatObj->responseMsg();  
  7. }else{  
  8.     $wechatObj->valid();  
  9. }  
  10.   
  11. class wechatCallbackapiTest  
  12. {  
  13.     //验证签名  
  14.     public function valid()  
  15.     {  
  16.         $echoStr = $_GET["echostr"];  
  17.         $signature = $_GET["signature"];  
  18.         $timestamp = $_GET["timestamp"];  
  19.         $nonce = $_GET["nonce"];  
  20.         $token = TOKEN;  
  21.         $tmpArr = array($token, $timestamp, $nonce);  
  22.         sort($tmpArr);  
  23.         $tmpStr = implode($tmpArr);  
  24.         $tmpStr = sha1($tmpStr);  
  25.         if($tmpStr == $signature){  
  26.             echo $echoStr;  
  27.             exit;  
  28.         }  
  29.     }  
  30.   
  31.     public function responseMsg()  
  32.     {  
  33.         $postStr = $GLOBALS["HTTP_RAW_POST_DATA"];  
  34.         if (!empty($postStr)){  
  35.             $this->logger("R ".$postStr);  
  36.             $postObj = simplexml_load_string($postStr, ‘SimpleXMLElement‘, LIBXML_NOCDATA);  
  37.             $RX_TYPE = trim($postObj->MsgType);  
  38.   
  39.             $result = "";  
  40.             switch ($RX_TYPE)  
  41.             {  
  42.                 case "event":  
  43.                     $result = $this->receiveEvent($postObj);  
  44.                     break;  
  45.                 case "text":  
  46.                     $result = $this->receiveText($postObj);  
  47.                     break;  
  48.                 case "location":  
  49.                     $result = $this->receiveLocation($postObj);  
  50.                     break;  
  51.             }  
  52.             $this->logger("T ".$result);  
  53.             echo $result;  
  54.         }else {  
  55.             echo "";  
  56.             exit;  
  57.         }  
  58.     }  
  59.   
  60.     private function receiveEvent($object)  
  61.     {  
  62.         switch ($object->Event)  
  63.         {  
  64.             case "subscribe":  
  65.                 $content =  "感谢您关注【微微微时代】"."\n"."微信号:vvvtimes"."\n"."微信原始ID:gh_f420fbb7e319"."\n";  
  66.                 break;  
  67.         }  
  68.         $result = $this->transmitText($object, $content);  
  69.         return $result;  
  70.     }  
  71.   
  72.     private function receiveText($object)  
  73.     {  
  74.         $keyword = trim($object->Content);  
  75.         require_once ‘./Weather.php‘;  
  76.         $weather = new Weather();  
  77.         $output = $weather->locationToWeatherResult($keyword);  
  78.         $content = json_decode($output, true);  
  79.   
  80.         $result = $this->transmitNews($object, $content);  
  81.         return $result;  
  82.     }  
  83.   
  84.     private function receiveLocation($object)  
  85.     {  
  86.         $location_xpoint = $object->Location_X;  
  87.         $location_ypoint = $object->Location_Y;  
  88.         $keyword = $location_ypoint.",".$location_xpoint;  
  89.         require_once ‘./Weather.php‘;  
  90.         $weather = new Weather();  
  91.         $output = $weather->locationToWeatherResult($keyword);  
  92.         $content = json_decode($output, true);  
  93.   
  94.         $result = $this->transmitNews($object, $content);  
  95.         return $result;  
  96.     }  
  97.   
  98.     private function transmitText($object, $content)  
  99.     {  
  100.         if (!isset($content) || empty($content)){  
  101.             return "";  
  102.         }  
  103.         $textTpl = "<xml>  
  104.                     <ToUserName><![CDATA[%s]]></ToUserName>  
  105.                     <FromUserName><![CDATA[%s]]></FromUserName>  
  106.                     <CreateTime>%s</CreateTime>  
  107.                     <MsgType><![CDATA[text]]></MsgType>  
  108.                     <Content><![CDATA[%s]]></Content>  
  109.                     </xml>";  
  110.         $result = sprintf($textTpl, $object->FromUserName, $object->ToUserName, time(), $content);  
  111.         return $result;  
  112.     }  
  113.   
  114.     private function transmitNews($object, $weatherContent)  
  115.     {  
  116.         $city = $weatherContent[‘results‘][0][‘currentCity‘];  
  117.         $index_data = $weatherContent[‘results‘][0][‘index‘];//指数  
  118.         $weather_data = $weatherContent[‘results‘][0][‘weather_data‘];  
  119.         $pm25= $weatherContent[‘results‘][0][‘pm25‘];  
  120.   
  121.         if($weatherContent[‘error‘]!=0){  
  122.             return "";  
  123.         }  
  124.         $itemTpl = "<item>  
  125.                     <Title><![CDATA[%s]]></Title>  
  126.                     <Description><![CDATA[%s]]></Description>  
  127.                     <PicUrl><![CDATA[%s]]></PicUrl>  
  128.                     <Url><![CDATA[%s]]></Url>  
  129.                     </item>";  
  130.         $item_str=‘‘;  
  131.         //标题1条,指数6条,天气4条,微信最大是10条图文,所以抽2条指数显示  
  132.         $title=$city.‘天气预报 ‘."PM2.5:".$pm25;  
  133.         $description=‘‘;  
  134.         $picUrl= ‘‘;  
  135.         $url=‘‘;  
  136.         $item_str = sprintf($itemTpl, $title, $description, $picUrl, $url);  
  137.         $newIndex_data= Array($index_data[0],$index_data[3]);  
  138.         foreach ($newIndex_data as $item){  
  139.             $title = $item[‘tipt‘].":".$item[‘des‘];  
  140.             $description=‘‘;  
  141.             $picUrl= ‘‘;  
  142.             $url=‘‘;  
  143.             $item_str .= sprintf($itemTpl, $title, $description, $picUrl, $url);  
  144.         }  
  145.         foreach ($weather_data as $item){  
  146.             $title = $item[‘date‘].$item[‘weather‘].$item[‘temperature‘];  
  147.             $description=‘‘;  
  148.             $picUrl= $item[‘dayPictureUrl‘];  
  149.             $url=‘‘;  
  150.             $item_str .= sprintf($itemTpl, $title, $description, $picUrl, $url);  
  151.         }  
  152.         $newsTpl = "<xml>  
  153.                     <ToUserName><![CDATA[%s]]></ToUserName>  
  154.                     <FromUserName><![CDATA[%s]]></FromUserName>  
  155.                     <CreateTime>%s</CreateTime>  
  156.                     <MsgType><![CDATA[news]]></MsgType>  
  157.                     <Content><![CDATA[]]></Content>  
  158.                     <ArticleCount>%s</ArticleCount>  
  159.                     <Articles>  
  160.                     $item_str</Articles>  
  161.                     </xml>";  
  162.   
  163.         $result = sprintf($newsTpl, $object->FromUserName, $object->ToUserName, time(), count($newIndex_data)+count($weather_data)+1);  
  164.         return $result;  
  165.     }  
  166.   
  167.     private function logger($log_content)  
  168.     {  
  169.   
  170.     }  
  171. }  
  172. ?>  

 

使用时,替换掉百度的AK,SK,替换掉微信的TOKEN即可

效果如下

微信公众号开发之天气应用

微信公众号开发之天气应用

微信公众号开发之天气应用

上一篇:一次神奇的Azure speech to text rest api之旅


下一篇:封装实践——打造微信底部tab栏