微信之开发接口PHP SDK完整版
白羽 2018-06-12 来源 :网络 阅读 476 评论 0

摘要:官方提供的SDK只有一个文本消息功能,我们将所有消息的消息类型及事件响应都整理了进来,并且加入日志记录,代码如下: 更新日志: 2013-01-01 版本1.0,包含Token验证及基本消息接口的收发2014-03-15 增加图片、视频、语音的内容回复2014-04-09 增加菜单链接事件... 官方提供的SDK只有一个文本消息功能,我们将所有消息的消息类型及事件响应都整理了进来,并且加入日志记录。


更新日志:

2013-01-01 版本1.0,包含Token验证及基本消息接口的收发
2014-03-15 增加图片、视频、语音的内容回复
2014-04-09 增加菜单链接事件
2014-04-10 修改文本回复的判定方法
2014-05-20 增加高级群发消息通知事件
2014-05-26 增加多客服消息及多客服的判定方法
2014-05-27 修改自动回复判定方式
2014-06-20 修复多图文回复的Bug
2014-07-10 增加第三方接口处理样式
2014-08-02 增加Emoji表格的回复处理
2014-10-01 增加自定义菜单扫一扫、发图片、发地理位置等接口的处理
2014-10-25 增加消息体签名及加解密的支持
2014-11-07 增加该公众号暂时无法提供服务请稍后再试的兼容
2014-12-20 移除高级群发消息通知事件,必要性不大
2015-02-23 移除消息体签名及加解密的支持,必要性不大
2015-04-07 优化客服模式和自动回复模式的判定
2015-05-16 优化日志记录,兼容SAE和自有主机

 

  1 <?php  2 /*  3     方倍工作室 //www.fangbei.org/  4     CopyRight 2015 All Rights Reserved  5 */  6   7 define("TOKEN", "weixin");  8   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             if (($postObj->MsgType == "event") && ($postObj->Event == "subscribe" || $postObj->Event == "unsubscribe")){ 46                 //过滤关注和取消关注事件 47             }else{ 48                  49             } 50              51             //消息类型分离 52             switch ($RX_TYPE) 53             { 54                 case "event": 55                     $result = $this->receiveEvent($postObj); 56                     break; 57                 case "text": 58                    if (strstr($postObj->Content, "第三方")){ 59                         $result = $this->relayPart3("//www.fangbei.org/test.php".'?'.$_SERVER['QUERY_STRING'], $postStr); 60                     }else{ 61                         $result = $this->receiveText($postObj); 62                     } 63                     break; 64                 case "image": 65                     $result = $this->receiveImage($postObj); 66                     break; 67                 case "location": 68                     $result = $this->receiveLocation($postObj); 69                     break; 70                 case "voice": 71                     $result = $this->receiveVoice($postObj); 72                     break; 73                 case "video": 74                     $result = $this->receiveVideo($postObj); 75                     break; 76                 case "link": 77                     $result = $this->receiveLink($postObj); 78                     break; 79                 default: 80                     $result = "unknown msg type: ".$RX_TYPE; 81                     break; 82             } 83             $this->logger("T \r\n".$result); 84             echo $result; 85         }else { 86             echo ""; 87             exit; 88         } 89     } 90  91     //接收事件消息 92     private function receiveEvent($object) 93     { 94         $content = ""; 95         switch ($object->Event) 96         { 97             case "subscribe": 98                 $content = "欢迎关注方倍工作室 "; 99                 $content .= (!empty($object->EventKey))?("\n来自二维码场景 ".str_replace("qrscene_","",$object->EventKey)):"";100                 break;101             case "unsubscribe":102                 $content = "取消关注";103                 break;104             case "CLICK":105                 switch ($object->EventKey)106                 {107                     case "COMPANY":108                         $content = array();109                         $content[] = array("Title"=>"方倍工作室", "Description"=>"", "PicUrl"=>"//discuz.comli.com/weixin/weather/icon/cartoon.jpg", "Url" =>"//m.cnblogs.com/?u=txw1958");110                         break;111                     default:112                         $content = "点击菜单:".$object->EventKey;113                         break;114                 }115                 break;116             case "VIEW":117                 $content = "跳转链接 ".$object->EventKey;118                 break;119             case "SCAN":120                 $content = "扫描场景 ".$object->EventKey;121                 break;122             case "LOCATION":123                 $content = "上传位置:纬度 ".$object->Latitude.";经度 ".$object->Longitude;124                 break;125             case "scancode_waitmsg":126                 if ($object->ScanCodeInfo->ScanType == "qrcode"){127                     $content = "扫码带提示:类型 二维码 结果:".$object->ScanCodeInfo->ScanResult;128                 }else if ($object->ScanCodeInfo->ScanType == "barcode"){129                     $codeinfo = explode(",",strval($object->ScanCodeInfo->ScanResult));130                     $codeValue = $codeinfo[1];131                     $content = "扫码带提示:类型 条形码 结果:".$codeValue;132                 }else{133                     $content = "扫码带提示:类型 ".$object->ScanCodeInfo->ScanType." 结果:".$object->ScanCodeInfo->ScanResult;134                 }135                 break;136             case "scancode_push":137                 $content = "扫码推事件";138                 break;139             case "pic_sysphoto":140                 $content = "系统拍照";141                 break;142             case "pic_weixin":143                 $content = "相册发图:数量 ".$object->SendPicsInfo->Count;144                 break;145             case "pic_photo_or_album":146                 $content = "拍照或者相册:数量 ".$object->SendPicsInfo->Count;147                 break;148             case "location_select":149                 $content = "发送位置:标签 ".$object->SendLocationInfo->Label;150                 break;151             default:152                 $content = "receive a new event: ".$object->Event;153                 break;154         }155 156         if(is_array($content)){157             if (isset($content[0]['PicUrl'])){158                 $result = $this->transmitNews($object, $content);159             }else if (isset($content['MusicUrl'])){160                 $result = $this->transmitMusic($object, $content);161             }162         }else{163             $result = $this->transmitText($object, $content);164         }165         return $result;166     }167 168     //接收文本消息169     private function receiveText($object)170     {171         $keyword = trim($object->Content);172         //多客服人工回复模式173         if (strstr($keyword, "请问在吗") || strstr($keyword, "在线客服")){174             $result = $this->transmitService($object);175             return $result;176         }177 178         //自动回复模式179         if (strstr($keyword, "文本")){180             $content = "这是个文本消息";181         }else if (strstr($keyword, "表情")){182             $content = "中国:".$this->bytes_to_emoji(0x1F1E8).$this->bytes_to_emoji(0x1F1F3)."\n仙人掌:".$this->bytes_to_emoji(0x1F335);183         }else if (strstr($keyword, "单图文")){184             $content = array();185             $content[] = array("Title"=>"单图文标题",  "Description"=>"单图文内容", "PicUrl"=>"//discuz.comli.com/weixin/weather/icon/cartoon.jpg", "Url" =>"//m.cnblogs.com/?u=txw1958");186         }else if (strstr($keyword, "图文") || strstr($keyword, "多图文")){187             $content = array();188             $content[] = array("Title"=>"多图文1标题", "Description"=>"", "PicUrl"=>"//discuz.comli.com/weixin/weather/icon/cartoon.jpg", "Url" =>"//m.cnblogs.com/?u=txw1958");189             $content[] = array("Title"=>"多图文2标题", "Description"=>"", "PicUrl"=>"//d.hiphotos.bdimg.com/wisegame/pic/item/f3529822720e0cf3ac9f1ada0846f21fbe09aaa3.jpg", "Url" =>"//m.cnblogs.com/?u=txw1958");190             $content[] = array("Title"=>"多图文3标题", "Description"=>"", "PicUrl"=>"//g.hiphotos.bdimg.com/wisegame/pic/item/18cb0a46f21fbe090d338acc6a600c338644adfd.jpg", "Url" =>"//m.cnblogs.com/?u=txw1958");191         }else if (strstr($keyword, "音乐")){192             $content = array();193             $content = array("Title"=>"最炫民族风", "Description"=>"歌手:凤凰传奇", "MusicUrl"=>"//121.199.4.61/music/zxmzf.mp3", "HQMusicUrl"=>"//121.199.4.61/music/zxmzf.mp3"); 194         }else{195             $content = date("Y-m-d H:i:s",time())."\nOpenID:".$object->FromUserName."\n技术支持 方倍工作室";196         }197 198         if(is_array($content)){199             if (isset($content[0])){200                 $result = $this->transmitNews($object, $content);201             }else if (isset($content['MusicUrl'])){202                 $result = $this->transmitMusic($object, $content);203             }204         }else{205             $result = $this->transmitText($object, $content);206         }207         return $result;208     }209 210     //接收图片消息211     private function receiveImage($object)212     {213         $content = array("MediaId"=>$object->MediaId);214         $result = $this->transmitImage($object, $content);215         return $result;216     }217 218     //接收位置消息219     private function receiveLocation($object)220     {221         $content = "你发送的是位置,经度为:".$object->Location_Y.";纬度为:".$object->Location_X.";缩放级别为:".$object->Scale.";位置为:".$object->Label;222         $result = $this->transmitText($object, $content);223         return $result;224     }225 226     //接收语音消息227     private function receiveVoice($object)228     {229         if (isset($object->Recognition) && !empty($object->Recognition)){230             $content = "你刚才说的是:".$object->Recognition;231             $result = $this->transmitText($object, $content);232         }else{233             $content = array("MediaId"=>$object->MediaId);234             $result = $this->transmitVoice($object, $content);235         }236         return $result;237     }238 239     //接收视频消息240     private function receiveVideo($object)241     {242         $content = array("MediaId"=>$object->MediaId, "ThumbMediaId"=>$object->ThumbMediaId, "Title"=>"", "Description"=>"");243         $result = $this->transmitVideo($object, $content);244         return $result;245     }246 247     //接收链接消息248     private function receiveLink($object)249     {250         $content = "你发送的是链接,标题为:".$object->Title.";内容为:".$object->Description.";链接地址为:".$object->Url;251         $result = $this->transmitText($object, $content);252         return $result;253     }254 255     //回复文本消息256     private function transmitText($object, $content)257     {258         if (!isset($content) || empty($content)){259             return "";260         }261 262         $xmlTpl = "<xml>263     <ToUserName><![CDATA[%s]]></ToUserName>264     <FromUserName><![CDATA[%s]]></FromUserName>265     <CreateTime>%s</CreateTime>266     <MsgType><![CDATA[text]]></MsgType>267     <Content><![CDATA[%s]]></Content>268 </xml>";269         $result = sprintf($xmlTpl, $object->FromUserName, $object->ToUserName, time(), $content);270 271         return $result;272     }273 274     //回复图文消息275     private function transmitNews($object, $newsArray)276     {277         if(!is_array($newsArray)){278             return "";279         }280         $itemTpl = "        <item>281             <Title><![CDATA[%s]]></Title>282             <Description><![CDATA[%s]]></Description>283             <PicUrl><![CDATA[%s]]></PicUrl>284             <Url><![CDATA[%s]]></Url>285         </item>286 ";287         $item_str = "";288         foreach ($newsArray as $item){289             $item_str .= sprintf($itemTpl, $item['Title'], $item['Description'], $item['PicUrl'], $item['Url']);290         }291         $xmlTpl = "<xml>292     <ToUserName><![CDATA[%s]]></ToUserName>293     <FromUserName><![CDATA[%s]]></FromUserName>294     <CreateTime>%s</CreateTime>295     <MsgType><![CDATA[news]]></MsgType>296     <ArticleCount>%s</ArticleCount>297     <Articles>298 $item_str    </Articles>299 </xml>";300 301         $result = sprintf($xmlTpl, $object->FromUserName, $object->ToUserName, time(), count($newsArray));302         return $result;303     }304 305     //回复音乐消息306     private function transmitMusic($object, $musicArray)307     {308         if(!is_array($musicArray)){309             return "";310         }311         $itemTpl = "<Music>312         <Title><![CDATA[%s]]></Title>313         <Description><![CDATA[%s]]></Description>314         <MusicUrl><![CDATA[%s]]></MusicUrl>315         <HQMusicUrl><![CDATA[%s]]></HQMusicUrl>316     </Music>";317 318         $item_str = sprintf($itemTpl, $musicArray['Title'], $musicArray['Description'], $musicArray['MusicUrl'], $musicArray['HQMusicUrl']);319 320         $xmlTpl = "<xml>321     <ToUserName><![CDATA[%s]]></ToUserName>322     <FromUserName><![CDATA[%s]]></FromUserName>323     <CreateTime>%s</CreateTime>324     <MsgType><![CDATA[music]]></MsgType>325     $item_str326 </xml>";327 328         $result = sprintf($xmlTpl, $object->FromUserName, $object->ToUserName, time());329         return $result;330     }331 332     //回复图片消息333     private function transmitImage($object, $imageArray)334     {335         $itemTpl = "<Image>336         <MediaId><![CDATA[%s]]></MediaId>337     </Image>";338 339         $item_str = sprintf($itemTpl, $imageArray['MediaId']);340 341         $xmlTpl = "<xml>342     <ToUserName><![CDATA[%s]]></ToUserName>343     <FromUserName><![CDATA[%s]]></FromUserName>344     <CreateTime>%s</CreateTime>345     <MsgType><![CDATA[image]]></MsgType>346     $item_str347 </xml>";348 349         $result = sprintf($xmlTpl, $object->FromUserName, $object->ToUserName, time());350         return $result;351     }352 353     //回复语音消息354     private function transmitVoice($object, $voiceArray)355     {356         $itemTpl = "<Voice>357         <MediaId><![CDATA[%s]]></MediaId>358     </Voice>";359 360         $item_str = sprintf($itemTpl, $voiceArray['MediaId']);361         $xmlTpl = "<xml>362     <ToUserName><![CDATA[%s]]></ToUserName>363     <FromUserName><![CDATA[%s]]></FromUserName>364     <CreateTime>%s</CreateTime>365     <MsgType><![CDATA[voice]]></MsgType>366     $item_str367 </xml>";368 369         $result = sprintf($xmlTpl, $object->FromUserName, $object->ToUserName, time());370         return $result;371     }372 373     //回复视频消息374     private function transmitVideo($object, $videoArray)375     {376         $itemTpl = "<Video>377         <MediaId><![CDATA[%s]]></MediaId>378         <ThumbMediaId><![CDATA[%s]]></ThumbMediaId>379         <Title><![CDATA[%s]]></Title>380         <Description><![CDATA[%s]]></Description>381     </Video>";382 383         $item_str = sprintf($itemTpl, $videoArray['MediaId'], $videoArray['ThumbMediaId'], $videoArray['Title'], $videoArray['Description']);384 385         $xmlTpl = "<xml>386     <ToUserName><![CDATA[%s]]></ToUserName>387     <FromUserName><![CDATA[%s]]></FromUserName>388     <CreateTime>%s</CreateTime>389     <MsgType><![CDATA[video]]></MsgType>390     $item_str391 </xml>";392 393         $result = sprintf($xmlTpl, $object->FromUserName, $object->ToUserName, time());394         return $result;395     }396 397     //回复多客服消息398     private function transmitService($object)399     {400         $xmlTpl = "<xml>401     <ToUserName><![CDATA[%s]]></ToUserName>402     <FromUserName><![CDATA[%s]]></FromUserName>403     <CreateTime>%s</CreateTime>404     <MsgType><![CDATA[transfer_customer_service]]></MsgType>405 </xml>";406         $result = sprintf($xmlTpl, $object->FromUserName, $object->ToUserName, time());407         return $result;408     }409 410     //回复第三方接口消息411     private function relayPart3($url, $rawData)412     {413         $headers = array("Content-Type: text/xml; charset=utf-8");414         $ch = curl_init();415         curl_setopt($ch, CURLOPT_URL, $url);416         curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);417         curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);418         curl_setopt($ch, CURLOPT_POST, 1);419         curl_setopt($ch, CURLOPT_POSTFIELDS, $rawData);420         $output = curl_exec($ch);421         curl_close($ch);422         return $output;423     }424 425     //字节转Emoji表情426     function bytes_to_emoji($cp)427     {428         if ($cp > 0x10000){       # 4 bytes429             return chr(0xF0 | (($cp & 0x1C0000) >> 18)).chr(0x80 | (($cp & 0x3F000) >> 12)).chr(0x80 | (($cp & 0xFC0) >> 6)).chr(0x80 | ($cp & 0x3F));430         }else if ($cp > 0x800){   # 3 bytes431             return chr(0xE0 | (($cp & 0xF000) >> 12)).chr(0x80 | (($cp & 0xFC0) >> 6)).chr(0x80 | ($cp & 0x3F));432         }else if ($cp > 0x80){    # 2 bytes433             return chr(0xC0 | (($cp & 0x7C0) >> 6)).chr(0x80 | ($cp & 0x3F));434         }else{                    # 1 byte435             return chr($cp);436         }437     }438 439     //日志记录440     private function logger($log_content)441     {442         if(isset($_SERVER['HTTP_APPNAME'])){   //SAE443             sae_set_display_errors(false);444             sae_debug($log_content);445             sae_set_display_errors(true);446         }else if($_SERVER['REMOTE_ADDR'] != "127.0.0.1"){ //LOCAL447             $max_size = 1000000;448             $log_filename = "log.xml";449             if(file_exists($log_filename) and (abs(filesize($log_filename)) > $max_size)){unlink($log_filename);}450             file_put_contents($log_filename, date('Y-m-d H:i:s')." ".$log_content."\r\n", FILE_APPEND);451         }452     }453 }454 ?>

 


 


本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标移动开发之微信频道!


本文由 @白羽 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程