讀古今文學網 > 微信公眾平台開發:從零基礎到ThinkPHP5高性能框架實踐 > 4.4 案例實踐 >

4.4 案例實踐

4.4.1 微信基礎消息SDK

基礎消息的SDK將前面章節的各種接收消息類型進行了處理,另外對被動發送消息類型進行了定義。其代碼如下。


  1 <?php
  2 /*
  3     方倍工作室 http:// www.fangbei.org/
  4     CopyRight 2016 All Rights Reserved
  5 */
  6 header('Content-type:text');
  7 
  8 define("TOKEN", "weixin");
  9 $wechatObj = new wechatCallbackapiTest;
 10 if (!isset($_GET['echostr'])) {
 11     $wechatObj->responseMsg;
 12 }else{
 13     $wechatObj->valid;
 14 }
 15 
 16 class wechatCallbackapiTest
 17 {
 18     // 驗證簽名
 19     public function valid
 20     {
 21         $echoStr = $_GET["echostr"];
 22         $signature = $_GET["signature"];
 23         $timestamp = $_GET["timestamp"];
 24         $nonce = $_GET["nonce"];
 25         $token = TOKEN;
 26         $tmpArr = array($token, $timestamp, $nonce);
 27         sort($tmpArr, SORT_STRING);
 28         $tmpStr = implode($tmpArr);
 29         $tmpStr = sha1($tmpStr);
 30         if($tmpStr == $signature){
 31             echo $echoStr;
 32             exit;
 33         }
 34     }
 35 
 36     // 響應消息
 37     public function responseMsg
 38     {
 39         $postStr = $GLOBALS["HTTP_RAW_POST_DATA"];
 40         if (!empty($postStr)){
 41             $this->logger("R \r\n".$postStr);
 42             $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_
                NOCDATA);
 43             $RX_TYPE = trim($postObj->MsgType);
 44             
 45             // 消息類型分離
 46             switch ($RX_TYPE)
 47             {
 48                 case "event":                // 事件
 49                     $result = $this->receiveEvent($postObj);
 50                     break;
 51                 case "text":                // 文本
 52                     $result = $this->receiveText($postObj);
 53                     break;
 54                 case "image":                // 圖片
 55                     $result = $this->receiveImage($postObj);
 56                     break;
 57                 case "location":        // 位置
 58                     $result = $this->receiveLocation($postObj);
 59                     break;
 60                 case "voice":                // 語音
 61                     $result = $this->receiveVoice($postObj);
 62                     break;
 63                 case "video":                // 視頻
 64                 case "shortvideo":
 65                     $result = $this->receiveVideo($postObj);
 66                     break;
 67                 case "link":                // 鏈接
 68                     $result = $this->receiveLink($postObj);
 69                     break;
 70                 default:
 71                     $result = "unknown msg type: ".$RX_TYPE;
 72                     break;
 73             }
 74             $this->logger("T \r\n".$result);
 75             echo $result;
 76         }else {
 77             echo "";
 78             exit;
 79         }
 80     }
 81 
 82     // 接收事件消息
 83     private function receiveEvent($object)
 84     {
 85         $content = "";
 86         switch ($object->Event)
 87         {
 88             case "subscribe":
 89                 $content = "歡迎關注方倍工作室 \n請回復以下關鍵字:文本 表情 單圖文 多
        圖文 音樂\n請按住說話 或 點擊 + 再分別發送以下內容:語音 圖片 小視頻 我的收藏 位置";
 90                 break;
 91             case "unsubscribe":
 92                 $content = "取消關注";
 93                 break;
 94             default:
 95                 $content = "receive a new event: ".$object->Event;
 96                 break;
 97         }
 98 
 99         if(is_array($content)){
100             $result = $this->transmitNews($object, $content);
101         }else{
102             $result = $this->transmitText($object, $content);
103         }
104         return $result;
105     }
106 
107     // 接收文本消息
108     private function receiveText($object)
109     {
110         $keyword = trim($object->Content);
111 
112         if (strstr($keyword, "文本")){                // 回覆文本
113             $content = "這是個文本消息";
114         }else if (strstr($keyword, "表情")){
115             $content = "微笑:/::)\n乒乓:/:oo\n中國:".$this->bytes_to_emoji(0x
        1F1E8).$this->bytes_to_emoji(0x1F1F3)."\n仙人掌:".$this->bytes_to_emoji(0x1F335);
116         }else if (strstr($keyword, "單圖文")){        // 回復圖文消息
117             $content = array;
118             $content = array("Title"=>"單圖文標題",  "Description"=>"單圖文內
        容", "PicUrl"=>"http:// discuz.comli.com/weixin/weather/icon/cartoon.jpg", 
        "Url" =>"http:// m.cnblogs.com/?u=txw1958");
119         }else if (strstr($keyword, "圖文") || strstr($keyword, "多圖文")){
120             $content = array;
121             $content = array("Title"=>"多圖文1標題", "Description"=>"", "Pic
        Url"=>"http:// discuz.comli.com/weixin/weather/icon/cartoon.jpg", "Url" =>
        "http:// m.cnblogs.com/?u=txw1958");
122             $content = array("Title"=>"多圖文2標題", "Description"=>"", "Pic
        Url"=>"http:// d.hiphotos.bdimg.com/wisegame/pic/item/f3529822720e0cf3ac9f
        1ada0846f21fbe09aaa3.jpg", "Url" =>"http:// m.cnblogs.com/?u=txw1958");
123             $content = array("Title"=>"多圖文3標題", "Description"=>"", "Pic
        Url"=>"http:// g.hiphotos.bdimg.com/wisegame/pic/item/18cb0a46f21fbe09
        0d338acc6a600c338644adfd.jpg", "Url" =>"http:// m.cnblogs.com/?u=txw1958");
124         }else if (strstr($keyword, "音樂")){                // 回復音樂消息
125             $content = array;
126             $content = array("Title"=>"最炫民族風", "Description"=>"歌手:鳳凰傳
        奇", "MusicUrl"=>"http:// mascot-music.stor.sinaapp.com/zxmzf.mp3", "HQMu
        sicUrl"=>"http:// mascot-music.stor.sinaapp.com/zxmzf.mp3"); 
127         }else{
128             $content = date("Y-m-d H:i:s",time)."\nOpenID:".$object->FromUser
        Name."\n技術支持 方倍工作室";
129         }
130 
131         if(is_array($content)){
132             if (isset($content[0])){
133                 $result = $this->transmitNews($object, $content);
134             }else if (isset($content['MusicUrl'])){
135                 $result = $this->transmitMusic($object, $content);
136             }
137         }else{
138             $result = $this->transmitText($object, $content);
139         }
140         return $result;
141     }
142 
143     // 接收圖片消息
144     private function receiveImage($object)
145     {
146         $content = array("MediaId"=>$object->MediaId);
147         $result = $this->transmitImage($object, $content);
148         return $result;
149     }
150 
151     // 接收位置消息
152     private function receiveLocation($object)
153     {
154         $content = "你發送的是位置,經度為:".$object->Location_Y.";緯度為:".$ob
        ject->Location_X.";縮放級別為:".$object->Scale.";位置為:".$object->Label;
155         $result = $this->transmitText($object, $content);
156         return $result;
157     }
158 
159     // 接收語音消息
160     private function receiveVoice($object)
161     {
162         if (isset($object->Recognition) && !empty($object->Recognition)){
163             $content = "你剛才說的是:".$object->Recognition;
164             $result = $this->transmitText($object, $content);
165         }else{
166             $content = array("MediaId"=>$object->MediaId);
167             $result = $this->transmitVoice($object, $content);
168         }
169         return $result;
170     }
171 
172     // 接收視頻消息
173     private function receiveVideo($object)
174     {
175         $content = array("MediaId"=>$object->MediaId, "ThumbMediaId"=>$object->
            ThumbMediaId, "Title"=>"", "Description"=>"");
176         $result = $this->transmitVideo($object, $content);
177         return $result;
178     }
179 
180     // 接收鏈接消息
181     private function receiveLink($object)
182     {
183         $content = "你發送的是鏈接,標題為:".$object->Title.";內容為:".$object->
            Description.";鏈接地址為:".$object->Url;
184         $result = $this->transmitText($object, $content);
185         return $result;
186     }
187     
188     // 回覆文本消息
189     private function transmitText($object, $content)
190     {
191         if (!isset($content) || empty($content)){
192             return "";
193         }
194 
195         $xmlTpl = "<xml>
196                    <ToUserName><![CDATA[%s]]></ToUserName>
197                    <FromUserName><![CDATA[%s]]></FromUserName>
198                    <CreateTime>%s</CreateTime>
199                    <MsgType><![CDATA[text]]></MsgType>
200                    <Content><![CDATA[%s]]></Content>
201                    </xml>";
202         $result = sprintf($xmlTpl, $object->FromUserName, $object->ToUserName, 
        time, $content);
203 
204         return $result;
205     }
206 
207     // 回復圖文消息
208     private function transmitNews($object, $newsArray)
209     {
210         if(!is_array($newsArray)){
211             return "";
212         }
213         $itemTpl = "<item>
214                     <Title><![CDATA[%s]]></Title>
215                     <Description><![CDATA[%s]]></Description>
216                     <PicUrl><![CDATA[%s]]></PicUrl>
217                     <Url><![CDATA[%s]]></Url>
218                     </item>";
219             
220         $item_str = "";
221         foreach ($newsArray as $item){
222             $item_str .= sprintf($itemTpl, $item['Title'], $item['Description'], 
                $item['PicUrl'], $item['Url']);
223         }
224         $xmlTpl = "<xml>
225                    <ToUserName><![CDATA[%s]]></ToUserName>
226                    <FromUserName><![CDATA[%s]]></FromUserName>
227                    <CreateTime>%s</CreateTime>
228                    <MsgType><![CDATA[news]]></MsgType>
229                    <ArticleCount>%s</ArticleCount>
230                    <Articles>
231                    $item_str    </Articles>
232                    </xml>";
233 
234         $result = sprintf($xmlTpl, $object->FromUserName, $object->ToUserName, 
        time, count($newsArray));
235         return $result;
236     }
237 
238     // 回復音樂消息
239     private function transmitMusic($object, $musicArray)
240     {
241         if(!is_array($musicArray)){
242             return "";
243         }
244         $itemTpl = "<Music>
245                     <Title><![CDATA[%s]]></Title>
246                     <Description><![CDATA[%s]]></Description>
247                     <MusicUrl><![CDATA[%s]]></MusicUrl>
248                     <HQMusicUrl><![CDATA[%s]]></HQMusicUrl>
249                     </Music>";
250 
251         $item_str = sprintf($itemTpl, $musicArray['Title'], $musicArray['Des
        cription'], $musicArray['MusicUrl'], $musicArray['HQMusicUrl']);
252 
253         $xmlTpl = "<xml>
254                    <ToUserName><![CDATA[%s]]></ToUserName>
255                    <FromUserName><![CDATA[%s]]></FromUserName>
256                    <CreateTime>%s</CreateTime>
257                    <MsgType><![CDATA[music]]></MsgType>
258                    $item_str
259                    </xml>";
260 
261         $result = sprintf($xmlTpl, $object->FromUserName, $object->ToUserName, 
        time);
262         return $result;
263     }
264 
265     // 回復圖片消息
266     private function transmitImage($object, $imageArray)
267     {
268         $itemTpl = "<Image>
269                     <MediaId><![CDATA[%s]]></MediaId>
270                     </Image>";
271 
272         $item_str = sprintf($itemTpl, $imageArray['MediaId']);
273 
274         $xmlTpl = "<xml>
275                    <ToUserName><![CDATA[%s]]></ToUserName>
276                    <FromUserName><![CDATA[%s]]></FromUserName>
277                    <CreateTime>%s</CreateTime>
278                    <MsgType><![CDATA[image]]></MsgType>
279                    $item_str
280                    </xml>";
281 
282         $result = sprintf($xmlTpl, $object->FromUserName, $object->ToUserName, 
        time);
283         return $result;
284     }
285 
286     // 回復語音消息
287     private function transmitVoice($object, $voiceArray)
288     {
289         $itemTpl = "<Voice>
290                     <MediaId><![CDATA[%s]]></MediaId>
291                     </Voice>";
292 
293         $item_str = sprintf($itemTpl, $voiceArray['MediaId']);
294         $xmlTpl = "<xml>
295                    <ToUserName><![CDATA[%s]]></ToUserName>
296                    <FromUserName><![CDATA[%s]]></FromUserName>
297                    <CreateTime>%s</CreateTime>
298                    <MsgType><![CDATA[voice]]></MsgType>
299                    $item_str
300                    </xml>";
301 
302         $result = sprintf($xmlTpl, $object->FromUserName, $object->ToUserName, 
        time);
303         return $result;
304     }
305 
306     // 回復視頻消息
307     private function transmitVideo($object, $videoArray)
308     {
309         $itemTpl = "<Video>
310                     <MediaId><![CDATA[%s]]></MediaId>
311                     <ThumbMediaId><![CDATA[%s]]></ThumbMediaId>
312                     <Title><![CDATA[%s]]></Title>
313                     <Description><![CDATA[%s]]></Description>
314                     </Video>";
315 
316         $item_str = sprintf($itemTpl, $videoArray['MediaId'], $videoArray['Thu
        mbMediaId'], $videoArray['Title'], $videoArray['Description']);
317 
318         $xmlTpl = "<xml>
319                    <ToUserName><![CDATA[%s]]></ToUserName>
320                    <FromUserName><![CDATA[%s]]></FromUserName>
321                    <CreateTime>%s</CreateTime>
322                    <MsgType><![CDATA[video]]></MsgType>
323                    $item_str
324                    </xml>";
325 
326         $result = sprintf($xmlTpl, $object->FromUserName, $object->ToUserName, 
        time);
327         return $result;
328     }
329 
330     // 日誌記錄
331     private function logger($log_content)
332     {
333         if(isset($_SERVER['HTTP_APPNAME'])){   // SAE
334             sae_set_display_errors(false);
335             sae_debug($log_content);
336             sae_set_display_errors(true);
337         }else if($_SERVER['REMOTE_ADDR'] != "127.0.0.1"){ // LOCAL
338             $max_size = 1000000;
339             $log_filename = "log.xml";
340             if(file_exists($log_filename) and (abs(filesize($log_filename)) > $max_
                size)){unlink($log_filename);}
341             file_put_contents($log_filename, date('Y-m-d H:i:s')." ".$log_content.|
                "\r\n", FILE_APPEND);
342         }
343     }
344 }
345 ?>
 

在responseMsg方法中,先提取消息類型$postObj->MsgType,從而實現各種消息類型的分離。在類wechatCallbackapiTest中,為每種消息類型定義了接收方法。在每個方法中,返回消息的主要特徵值,組成文本信息作為內容回復。

在接收到文本指令回覆文本、圖文(包括單圖文和多圖文)、音樂3種消息時,是使用直接構造相應消息類型實現的,而圖片、語音、視頻3種消息需要MediaId參數,在這裡直接使用用戶發送過來的消息中的MediaId,然後組裝成響應消息回復。