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
- class Weather
- {
- var $ak = 'AK';
- var $sk = 'SK';
- var $url = 'http://api.map.baidu.com/telematics/v3/weather?location=%s&output=%s&ak=%s&sn=%s';
- var $uri = '/telematics/v3/weather';
- //计算sn
- function caculateAKSN($ak, $sk, $url, $querystring_arrays, $method = 'GET')
- {
- if ($method === 'POST'){
- ksort($querystring_arrays);
- }
- $querystring = http_build_query($querystring_arrays);
- return md5(urlencode($url.'?'.$querystring.$sk));
- }
- //$location可填地名或经纬度,$output可填json或xml
- //locationToWeatherResult('长沙');
- //locationToWeatherResult('121.67397,38.793570');
- public function locationToWeatherResult($location,$output='json'){
- //当前为GBK编码时需要转换
- //$location = iconv('GB2312','UTF-8',$location);
- //构造请求串数组
- $querystring_arrays = array (
- 'location' => $location,
- 'output' => $output,
- 'ak' => $this->ak
- );
- //调用sn计算函数,默认get请求
- $sn = $this->caculateAKSN($this->ak, $this->sk, $this->uri, $querystring_arrays);
- $target = sprintf($this->url, urlencode($location), $output, $this->ak, $sn);
- $content = file_get_contents($target);
- return $content;
- }
- }
- ?>
微信主页php页面
- <?php
- define("TOKEN", "token");
- $wechatObj = new wechatCallbackapiTest();
- if (!isset($_GET['echostr'])) {
- $wechatObj->responseMsg();
- }else{
- $wechatObj->valid();
- }
- class wechatCallbackapiTest
- {
- //验证签名
- public function valid()
- {
- $echoStr = $_GET["echostr"];
- $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){
- echo $echoStr;
- exit;
- }
- }
- public function responseMsg()
- {
- $postStr = $GLOBALS["HTTP_RAW_POST_DATA"];
- if (!empty($postStr)){
- $this->logger("R ".$postStr);
- $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
- $RX_TYPE = trim($postObj->MsgType);
- $result = "";
- switch ($RX_TYPE)
- {
- case "event":
- $result = $this->receiveEvent($postObj);
- break;
- case "text":
- $result = $this->receiveText($postObj);
- break;
- case "location":
- $result = $this->receiveLocation($postObj);
- break;
- }
- $this->logger("T ".$result);
- echo $result;
- }else {
- echo "";
- exit;
- }
- }
- private function receiveEvent($object)
- {
- switch ($object->Event)
- {
- case "subscribe":
- $content = "感谢您关注【微微微时代】"."\n"."微信号:vvvtimes"."\n"."微信原始ID:gh_f420fbb7e319"."\n";
- break;
- }
- $result = $this->transmitText($object, $content);
- return $result;
- }
- private function receiveText($object)
- {
- $keyword = trim($object->Content);
- require_once './Weather.php';
- $weather = new Weather();
- $output = $weather->locationToWeatherResult($keyword);
- $content = json_decode($output, true);
- $result = $this->transmitNews($object, $content);
- return $result;
- }
- private function receiveLocation($object)
- {
- $location_xpoint = $object->Location_X;
- $location_ypoint = $object->Location_Y;
- $keyword = $location_ypoint.",".$location_xpoint;
- require_once './Weather.php';
- $weather = new Weather();
- $output = $weather->locationToWeatherResult($keyword);
- $content = json_decode($output, true);
- $result = $this->transmitNews($object, $content);
- return $result;
- }
- private function transmitText($object, $content)
- {
- if (!isset($content) || empty($content)){
- return "";
- }
- $textTpl = "<xml>
- <ToUserName><![CDATA[%s]]></ToUserName>
- <FromUserName><![CDATA[%s]]></FromUserName>
- <CreateTime>%s</CreateTime>
- <MsgType><![CDATA[text]]></MsgType>
- <Content><![CDATA[%s]]></Content>
- </xml>";
- $result = sprintf($textTpl, $object->FromUserName, $object->ToUserName, time(), $content);
- return $result;
- }
- private function transmitNews($object, $weatherContent)
- {
- $city = $weatherContent['results'][0]['currentCity'];
- $index_data = $weatherContent['results'][0]['index'];//指数
- $weather_data = $weatherContent['results'][0]['weather_data'];
- $pm25= $weatherContent['results'][0]['pm25'];
- if($weatherContent['error']!=0){
- return "";
- }
- $itemTpl = "<item>
- <Title><![CDATA[%s]]></Title>
- <Description><![CDATA[%s]]></Description>
- <PicUrl><![CDATA[%s]]></PicUrl>
- <Url><![CDATA[%s]]></Url>
- </item>";
- $item_str='';
- //标题1条,指数6条,天气4条,微信最大是10条图文,所以抽2条指数显示
- $title=$city.'天气预报 '."PM2.5:".$pm25;
- $description='';
- $picUrl= '';
- $url='';
- $item_str = sprintf($itemTpl, $title, $description, $picUrl, $url);
- $newIndex_data= Array($index_data[0],$index_data[3]);
- foreach ($newIndex_data as $item){
- $title = $item['tipt'].":".$item['des'];
- $description='';
- $picUrl= '';
- $url='';
- $item_str .= sprintf($itemTpl, $title, $description, $picUrl, $url);
- }
- foreach ($weather_data as $item){
- $title = $item['date'].$item['weather'].$item['temperature'];
- $description='';
- $picUrl= $item['dayPictureUrl'];
- $url='';
- $item_str .= sprintf($itemTpl, $title, $description, $picUrl, $url);
- }
- $newsTpl = "<xml>
- <ToUserName><![CDATA[%s]]></ToUserName>
- <FromUserName><![CDATA[%s]]></FromUserName>
- <CreateTime>%s</CreateTime>
- <MsgType><![CDATA[news]]></MsgType>
- <Content><![CDATA[]]></Content>
- <ArticleCount>%s</ArticleCount>
- <Articles>
- $item_str</Articles>
- </xml>";
- $result = sprintf($newsTpl, $object->FromUserName, $object->ToUserName, time(), count($newIndex_data)+count($weather_data)+1);
- return $result;
- }
- private function logger($log_content)
- {
- }
- }
- ?>
使用时,替换掉百度的AK,SK,替换掉微信的TOKEN即可
效果如下