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,然后组装成响应消息回复。