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

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即可

效果如下


你可能感兴趣的:(百度,微信,天气,位置)