• 微信公众平台开发接口PHP SDK完整版


      1 <?php
      2 /*
      3     方倍工作室 http://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 
    ".$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("http://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 
    ".$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))?("
    来自二维码场景 ".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"=>"http://discuz.comli.com/weixin/weather/icon/cartoon.jpg", "Url" =>"http://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)."
    仙人掌:".$this->bytes_to_emoji(0x1F335);
    183         }else if (strstr($keyword, "单图文")){
    184             $content = array();
    185             $content[] = array("Title"=>"单图文标题",  "Description"=>"单图文内容", "PicUrl"=>"http://discuz.comli.com/weixin/weather/icon/cartoon.jpg", "Url" =>"http://m.cnblogs.com/?u=txw1958");
    186         }else if (strstr($keyword, "图文") || strstr($keyword, "多图文")){
    187             $content = array();
    188             $content[] = array("Title"=>"多图文1标题", "Description"=>"", "PicUrl"=>"http://discuz.comli.com/weixin/weather/icon/cartoon.jpg", "Url" =>"http://m.cnblogs.com/?u=txw1958");
    189             $content[] = array("Title"=>"多图文2标题", "Description"=>"", "PicUrl"=>"http://d.hiphotos.bdimg.com/wisegame/pic/item/f3529822720e0cf3ac9f1ada0846f21fbe09aaa3.jpg", "Url" =>"http://m.cnblogs.com/?u=txw1958");
    190             $content[] = array("Title"=>"多图文3标题", "Description"=>"", "PicUrl"=>"http://g.hiphotos.bdimg.com/wisegame/pic/item/18cb0a46f21fbe090d338acc6a600c338644adfd.jpg", "Url" =>"http://m.cnblogs.com/?u=txw1958");
    191         }else if (strstr($keyword, "音乐")){
    192             $content = array();
    193             $content = array("Title"=>"最炫民族风", "Description"=>"歌手:凤凰传奇", "MusicUrl"=>"http://121.199.4.61/music/zxmzf.mp3", "HQMusicUrl"=>"http://121.199.4.61/music/zxmzf.mp3"); 
    194         }else{
    195             $content = date("Y-m-d H:i:s",time())."
    OpenID:".$object->FromUserName."
    技术支持 方倍工作室";
    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_str
    326 </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_str
    347 </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_str
    367 </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_str
    391 </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 bytes
    429             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 bytes
    431             return chr(0xE0 | (($cp & 0xF000) >> 12)).chr(0x80 | (($cp & 0xFC0) >> 6)).chr(0x80 | ($cp & 0x3F));
    432         }else if ($cp > 0x80){    # 2 bytes
    433             return chr(0xC0 | (($cp & 0x7C0) >> 6)).chr(0x80 | ($cp & 0x3F));
    434         }else{                    # 1 byte
    435             return chr($cp);
    436         }
    437     }
    438 
    439     //日志记录
    440     private function logger($log_content)
    441     {
    442         if(isset($_SERVER['HTTP_APPNAME'])){   //SAE
    443             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"){ //LOCAL
    447             $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."
    ", FILE_APPEND);
    451         }
    452     }
    453 }
    454 ?>
  • 相关阅读:
    Samba 4.0 RC3 发布
    SymmetricDS 3.1.7 发布,数据同步和复制
    Express.js 3.0 发布,Node.js 的高性能封装
    GIFLIB 5.0.1 发布,C语言的GIF处理库
    jQuery UI 1.9.1 发布
    SVN Access Manager 0.5.5.14 发布 SVN 管理工具
    DynamicReports 3.0.3 发布 Java 报表工具
    HttpComponents HttpClient 4.2.2 GA 发布
    AppCan 2.0 正式发布,推移动应用云服务
    Ruby 2.0 的新功能已经冻结
  • 原文地址:https://www.cnblogs.com/kangshuai/p/4910366.html
Copyright © 2020-2023  润新知