上QQ阅读APP看书,第一时间看更新
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,然后组装成响应消息回复。