首页 >后端开发 >php教程 >PHP实现微信实时天气查询

PHP实现微信实时天气查询

韦小宝
韦小宝原创
2018-03-14 09:08:071784浏览

在我们开发微信公众号等微信应用的时候,我们都是希望功能越多越好,那么我们今天就来讲一下,PHP实现微信天气查询,其实并不是太复杂,只需要调用一下百度天气接口就可以了,废话不多说了,我们一起来看看吧!
 
我们要达到的效果如下图所示,当你在微信中输入某地天气如“深圳天气”字样是会出现以下页面:

微信效果图.jpeg
ps:这里声明一下,我使用的后台服务器是新浪sae服务器,这里不做过多介绍

第一页代码

这一页代码主要是用于token的验证、以及通过后台服务器对微信用户请求发出响应。这一页代码比较简单,不做介绍。

<?php
header("content-Type:text;charset=utf8;")
define("TOKEN", "weixin");

$wechatObj = new wechatCallbackapiTest();
if (!isset($_GET[&#39;echostr&#39;])) {
    $wechatObj->responseMsg();
}else{
    $wechatObj->valid();
}

class wechatCallbackapiTest
{
    public function valid()
    {
        $echoStr = $_GET["echostr"];
        if($this->checkSignature()){
            echo $echoStr;
            exit;
        }
    }

    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;
        }
    }

    public function responseMsg()
    {
        $postStr = $GLOBALS["HTTP_RAW_POST_DATA"];
        if (!empty($postStr)){
            $this->logger("R ".$postStr);
            $postObj = simplexml_load_string($postStr, &#39;SimpleXMLElement&#39;, LIBXML_NOCDATA);
            $RX_TYPE = trim($postObj->MsgType);

            switch ($RX_TYPE)
            {
                case "event":
                    $result = $this->receiveEvent($postObj);
                    break;
                case "text":
                    $result = $this->receiveText($postObj);
                    break;
            }
            $this->logger("T ".$result);
            echo $result;
        }else {
            echo "";
            exit;
        }
    }

    private function receiveEvent($object)
    {
        $content = "";
        switch ($object->Event)
        {
            case "subscribe":
                $content = "欢迎关注,查询天气,发送天气加城市名,如“深圳天气”";
                break;
            case "unsubscribe":
                $content = "取消关注";
                break;
        }
        $result = $this->transmitText($object, $content);
        return $result;
    }
  //str_replace(str1,str2,str3)用str3包含str1,用str2取代str1.
    private function receiveText($object)
    {
        $keyword = trim($object->Content);
        if (strstr($keyword, "天气")){
            $city = str_replace(&#39;天气&#39;, &#39;&#39;, $keyword);//这里用空格取代$keyword中的天气二字。
            include("weather2.php");
            $content = getWeatherInfo($city);
        //判断笑话
        }
        $result = $this->transmitNews($object, $content);
        return $result;
    }


    private function transmitText($object, $content)
    {
        $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, $arr_item)
    {
        if(!is_array($arr_item))
            return;

        $itemTpl = "    <item>
        <Title><![CDATA[%s]]></Title>
        <Description><![CDATA[%s]]></Description>
        <PicUrl><![CDATA[%s]]></PicUrl>
        <Url><![CDATA[%s]]></Url>
    </item>
";
        $item_str = "";
        foreach ($arr_item as $item)
            $item_str .= sprintf($itemTpl, $item[&#39;Title&#39;], $item[&#39;Description&#39;], $item[&#39;PicUrl&#39;], $item[&#39;Url&#39;]);

        $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($arr_item));
        return $result;
    }

    private function transmitMusic($object, $musicArray)
    {
        $itemTpl = "<Music>
    <Title><![CDATA[%s]]></Title>
    <Description><![CDATA[%s]]></Description>
    <MusicUrl><![CDATA[%s]]></MusicUrl>
    <HQMusicUrl><![CDATA[%s]]></HQMusicUrl>
</Music>";

        $item_str = sprintf($itemTpl, $musicArray[&#39;Title&#39;], $musicArray[&#39;Description&#39;], $musicArray[&#39;MusicUrl&#39;], $musicArray[&#39;HQMusicUrl&#39;]);

        $textTpl = "<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[music]]></MsgType>
$item_str
</xml>";

        $result = sprintf($textTpl, $object->FromUserName, $object->ToUserName, time());
        return $result;
    }
    //这里主要用于在服务器端生成日志
    private function logger($log_content)
    {
        if(isset($_SERVER[&#39;HTTP_BAE_ENV_APPID&#39;])){   //BAE
            require_once "BaeLog.class.php";
            $logger = BaeLog::getInstance();
            $logger ->logDebug($log_content);
        }else if(isset($_SERVER[&#39;HTTP_APPNAME&#39;])){   //SAE
            sae_set_display_errors(false);
            sae_debug($log_content);
            sae_set_display_errors(true);
        }else if($_SERVER[&#39;REMOTE_ADDR&#39;] != "127.0.0.1"){ //LOCAL
            $max_size = 10000;
            $log_filename = "log.xml";
            if(file_exists($log_filename) and (abs(filesize($log_filename)) > $max_size)){unlink($log_filename);}
            file_put_contents($log_filename, date(&#39;H:i:s&#39;)." ".$log_content."\r\n", FILE_APPEND);
        }
    }
}


?>

第二页代码

这一页代码主要关于调用百度天气接口的过程以及他们的数据传输方式。

1、我们要调用百度的天气接口,需要在百度地图开放平台进行注册,然后创建一个应用获取该应用ak和sk。

获取百度地图开放平台接口图1.jpg
获取ak(即access key)后,点击设置,页面如下:
百度地图开放平台图2.jpg
在请求校验方式哪里选择sn校验方式,会自动出现下方的sk码(即 Security Key)。

sk的具体作用和sn计算算法可参照下面这篇文章http://lbsyun.baidu.com/index.php?title=lbscloud/api/appendix

<?php

// var_dump(getWeatherInfo("桃江"));
getWeatherInfo("深圳");
function getWeatherInfo($cityName)
{
    if ($cityName == "" || (strstr($cityName, "+"))){
        return "发送天气加城市,例如&#39;天气深圳&#39;";
    }

    $ak = &#39;Plev804CmHUMwPXVcehCcB14Ths0zuat&#39;;//从百度地图开发平台获取的ak
    $sk = &#39;Iv3vSPCd2jnIlMlCrCgywGSkP9PaXiDC&#39;;//从百度地图开发平台获取的sk

//向百度地图开发平台请其数据的url如http://api.map.baidu.com/geocoder/v2/?address=百度大厦&output=json&ak=yourak**&sn=7de5a22212ffaa9e326444c75a58f9a0。包含4个参数,address(查询地址),output(请求数据的恢复格式)、ak(验证密钥)、sn是经过加密后的数据。

    $url = &#39;http://api.map.baidu.com/telematics/v3/weather?ak=%s&location=%s&output=%s&sn=%s&#39;;
    $uri = &#39;/telematics/v3/weather&#39;;
    $location = $cityName;
    $output = &#39;json&#39;;
    $querystring_arrays = array(
        &#39;ak&#39; => $ak,
        &#39;location&#39; => $location,
        &#39;output&#39; => $output
    );
    $querystring = http_build_query($querystring_arrays);//使用关联数组生成一个urlencode请求字符串。格式如下:ak=Plev804CmHUMwPXVcehCcB14Ths0zuat&location=深圳&output=json;
   // var_dump($querystring);
//urlencode()   url中的一些特殊字符和中文字符可能不被服务器所识别,需要经过urlencode()编码才能被识别。
    $sn = md5(urlencode($uri.&#39;?&#39;.$querystring.$sk));//md5()对url中的数据进行加密。
    $targetUrl = sprintf($url, $ak, urlencode($location), $output, $sn);
    // var_dump($targetUrl);

//curl用于与接口服务器建立会话获取 接口传递过来的数据。
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $targetUrl);//与接口简历会话
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//获取的数据存储在一个变量上,而不是直接输出。如果为o或false则直接输出。
    $result = curl_exec($ch);//执行会话,获取数据。
    echo $result;//字符串格式加数个json格式的数据类型
    curl_close($ch);
    $result = json_decode($result, true);//参数带true返回一个数组
    echo "</br>";
     echo "</br>";
      echo "</br>";
       echo "</br>";

        echo "</br>";
         echo "</br>";
          echo "</br>";
           echo "</br>";
    var_dump($result);
    if ($result["error"] != 0){
        return $result["status"];
    }
    $curHour = (int)date(&#39;H&#39;,time());
     echo "</br>";
         echo "</br>";
          echo "</br>";
           echo "</br>";
    echo $curHour;
    $weather = $result["results"][0];
    $weatherArray[] = array("Title" =>$weather[&#39;currentCity&#39;]."天气预报", "Description" =>"", "PicUrl" =>"", "Url" =>"");
    for ($i = 0; $i < count($weather["weather_data"]); $i++) {
        $weatherArray[] = array("Title"=>
            $weather["weather_data"][$i]["date"]."\n".
            $weather["weather_data"][$i]["weather"]." ".
            $weather["weather_data"][$i]["wind"]." ".
            $weather["weather_data"][$i]["temperature"],
        "Description"=>"", 
        "PicUrl"=>(($curHour >= 6) && ($curHour < 18))?$weather["weather_data"][$i]["dayPictureUrl"]:$weather["weather_data"][$i]["nightPictureUrl"], "Url"=>"");
    }
    return $weatherArray;
}


?>

以上就是本篇文章的所有内容,大家好好看看吧,对于刚开始接触微信开发的同学来讲本篇文章可能有点难度哦!    

相关推荐:

PHP微信开发之获取城市天气

以上是PHP实现微信实时天气查询的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn