在我們開發公眾號等應用的時候,我們都是希望功能越多越好,那麼我們今天就來講一下,PHP實現天氣查詢,其實並不是太複雜,只需要調用一下百度天氣介面就可以了,廢話不多說了,我們一起來看看吧!
我們要達到的效果如所示,當你在中輸入某地天氣如“深圳天氣”字樣是會出現以下頁面:
ps:這裡聲明一下,我使用的後台伺服器是新浪sae伺服器,這裡不做過多介紹
第一頁代碼
這一頁代碼主要是用於token的驗證、以及通過後台伺服器對使用者請求發出響應。這一頁代碼比較簡單,不做介紹。
<?phpheader("content-Type:text;charset=utf8;")define("TOKEN", "weixin");$wechatObj = new wechatCallbackapiTest();if (!isset($_GET['echostr'])) { $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, 'SimpleXMLElement', 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('天氣', '', $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['Title'], $item['Description'], $item['PicUrl'], $item['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($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['Title'], $musicArray['Description'], $musicArray['MusicUrl'], $musicArray['HQMusicUrl']); $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['HTTP_BAE_ENV_APPID'])){ //BAE require_once "BaeLog.class.php"; $logger = BaeLog::getInstance(); $logger ->logDebug($log_content); }else if(isset($_SERVER['HTTP_APPNAME'])){ //SAE sae_set_display_errors(false); sae_debug($log_content); sae_set_display_errors(true); }else if($_SERVER['REMOTE_ADDR'] != "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('H:i:s')." ".$log_content."\r\n", FILE_APPEND); } }}?>
第二頁代碼
這一頁代碼主要關於調用百度天氣介面的過程以及他們的資料轉送方式。
1、我們要調用百度的天氣介面,需要在百度地圖開放平台進行註冊,然後建立一個應用擷取該應用ak和sk。
擷取ak(即access key)後,點擊設定,頁面如下:
在請求校正方式哪裡選擇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 "發送天氣加城市,例如'天氣深圳'"; } $ak = 'Plev804CmHUMwPXVcehCcB14Ths0zuat';//從百度地圖開發平台擷取的ak $sk = 'Iv3vSPCd2jnIlMlCrCgywGSkP9PaXiDC';//從百度地圖開發平台擷取的sk//向百度地圖開發平台請其資料的url如http://api.map.baidu.com/geocoder/v2/?address=百度大廈&output=json&ak=yourak**&sn=7de5a22212ffaa9e326444c75a58f9a0。包含4個參數,address(查詢地址),output(請求資料的恢複格式)、ak(驗證密鑰)、sn是經過加密後的資料。 $url = 'http://api.map.baidu.com/telematics/v3/weather?ak=%s&location=%s&output=%s&sn=%s'; $uri = '/telematics/v3/weather'; $location = $cityName; $output = 'json'; $querystring_arrays = array( 'ak' => $ak, 'location' => $location, 'output' => $output ); $querystring = http_build_query($querystring_arrays);//使用關聯陣列產生一個urlencode請求字串。格式如下:ak=Plev804CmHUMwPXVcehCcB14Ths0zuat&location=深圳&output=json; // var_dump($querystring);//urlencode() url中的一些特殊字元和中文字元可能不被伺服器所識別,需要經過urlencode()編碼才能被識別。 $sn = md5(urlencode($uri.'?'.$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('H',time()); echo "</br>"; echo "</br>"; echo "</br>"; echo "</br>"; echo $curHour; $weather = $result["results"][0]; $weatherArray[] = array("Title" =>$weather['currentCity']."天氣預報", "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;}?>