程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> 關於PHP編程 >> PHP微信公眾平台開發 - 天氣預報功能開發

PHP微信公眾平台開發 - 天氣預報功能開發

編輯:關於PHP編程

【PHP微信公眾平台開發系列】

01.配置微信接口
02.公眾平台示例代碼分析
03.訂閱事件(subscribe)處理
04.簡單回復功能開發
05.API天氣預報功能開發


本文地址:http://www.phpchina.com/archives/view-43387-1.html
本系列由PHPChina特邀作者@David_Tang供稿,轉載請注明作者信息與本文地址。

一、簡介

前面幾篇文章對PHP微信公眾平台的開通及簡單使用做了簡單的介紹,但都沒有涉及到實際使用中的問題,例如天氣查詢,公交查詢,快遞查詢等。接下來的幾篇文章將對實際生活中會經常使用到的一些功能進行開發講解,以供讀者參考。

這一篇文章將對大家每天都會關心的天氣查詢進行開發,例如,用戶發送消息 “蘇州天氣”,則會返回蘇州實時天氣狀況,以及未來兩天甚至未來五天的天氣狀況。

二、思路分析

首先要對用戶發送過來的消息進行判斷,判斷消息裡是否含有“天氣”關鍵字,如果含有,則需要繼續提取地區信息,然後再通過中國天氣網(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個城市,以後還會繼續增加,請到 樂思樂享 官方論壇(URL:http://www.joythink.net/)下載吧。
 



=========================================================

PHPChina微信平台開通啦!

微信搜索“PHPChina”,點擊關注按鈕,即可獲得PPC為您推送的最新最專業的業界信息,更有更多專題欄目為您獻上

【PPC挖掘】: 不定時為您獻上經典產品與產品人的故事。
【PPC外文】: 不定時分享一篇外文翻譯文章
【PPC問答】: 每日集中回復關注用戶的提問
【Coder Radio Pro】:不定期廣播節目

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved