【微信公众平台03】自动回复

    之前尝试开发的过程中,遇到了很多困难,究其原因,还是对代码原理不甚了解,也没学过php相关知识,于是打算回过头来,一步一步再浅析一下相关文件。

    weixin.class文件主要作用是自动回复消息,我不是用上一篇推荐的SDK版本,可能现在用的这个版本更合我胃口,也更好理解,具体解析写在代码注释里吧。

    

<?php
require 'weixin.config.php';
$wechatObj = new wechatCallbackapiTest();  
//没有得到echostr 先验证  
if (!isset($_GET['echostr'])) {  
    $wechatObj->responseMsg();    //处理消息  
}else{  
    $wechatObj->valid();  
}  
/*$code = $_GET["code"]; 
$userinfo = getopenidtoken($code); 
$StrOpenid=$userinfo["openid"]; 
*/  
class wechatCallbackapiTest  
{  
    //验证消息  
    public function valid()  
    {  
        $echoStr = $_GET["echostr"];  
        if($this->checkSignature()){  
            echo $echoStr;  
            exit;  
        }  
    }  
  //上述消息验证似乎还有很多方法,具体原理我也不是很清楚,暂时存疑。
    //检查签名  
    private function checkSignature()  
    {  
        $signature = $_GET["signature"];  
        $timestamp = $_GET["timestamp"];  
        $nonce = $_GET["nonce"];  
        $token = TOKEN;  
        $tmpArr = array($token, $timestamp, $nonce);  
        sort($tmpArr, SORT_STRING);  
        $tmpStr = implode($tmpArr);  
        $tmpStr = sha1($tmpStr);  
  
        if($tmpStr == $signature){  
            return true;  
        }else{  
            return false;  
        }  
    }  
  
    //响应消息,这部分内容是用来对消息进行分类,以便用不同的类来响应。这样写代码封装性更好一些。  
    public function responseMsg()  
    {  
        $postStr = $GLOBALS["HTTP_RAW_POST_DATA"];  
        if (!empty($postStr)){  
            $this->logger("R ".$postStr);    //日志文件(R)   
            $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);  //获得对象信息  
            $RX_TYPE = trim($postObj->MsgType);  
  
            switch ($RX_TYPE)  
            {  
                case "event":               //处理点击事件  
                    $result = $this->receiveEvent($postObj);    //返回信息  
                    break;  
                case "text":                //处理文本信息  
                    $result = $this->receiveText($postObj);  
                    break;  
                case "image":               //处理图片  
                    $result = $this->receiveImage($postObj);  
                    break;  
                case "location":            //地理位置消息 
                    $result = $this->receiveLocation($postObj);  
                    break;  
                case "voice":               //处理声音  
                    $result = $this->receiveVoice($postObj);  
                    break;  
                case "video":  
                    $result = $this->receiveVideo($postObj);  
                    break;  
                case "link":  
                    $result = $this->receiveLink($postObj);  
                    break;  
                default:  
                    $result = "unknown msg type: ".$RX_TYPE;  
                    break;  
            }  
            $this->logger("T ".$result);  
            echo $result;  
        }else {  
            echo "";  
            exit;  
        }  
    }  
  
    //接收事件消息  
    private function receiveEvent($object)  
    {  
        $content = "";  
        switch ($object->Event)  
        {  
            case "subscribe":  
                $content = "欢迎来到xxxx ";  
                break;  //这里是用户点击关注公众号后系统回复的消息。
            case "unsubscribe":  
                $content = "取消关注";  
                break;  
            case "SCAN":  
                $content = "扫描场景 ".$object->EventKey;  
                break;  
            case "CLICK":  
                switch ($object->EventKey)  
                {  
                    case "COMPANY":  
                        $content = "xxxx";  
                        break;  
                    default:  
                        $content = "点击菜单:".$object->EventKey;  
                        break;  
                }  
                break;  //click和scan这两部分目前还不明白具体作用
            case "LOCATION":  
                $content = "上传位置:纬度 ".$object->Latitude.";经度 ".$object->Longitude;  
                break;  
            case "VIEW":  
                $content = "跳转链接 ".$object->EventKey;  
                break;  
            default:  
                $content = "receive a new event: ".$object->Event;  
                break;  
        }  
        $result = $this->transmitText($object, $content);  
        return $result;  
    }  
  
    //接收文本消息  
    private function receiveText($object)  
    {  
        switch ($object->Content)  
        {  
            case "文本":  
                $content = "这是个文本消息";  
                break;  
            case "音乐":  
                $content = array("Title"=>"最炫民族风", "Description"=>"歌手:凤凰传奇", "MusicUrl"=>"http://121.199.4.61/music/zxmzf.mp3", "HQMusicUrl"=>"http://121.199.4.61/music/zxmzf.mp3");  
                break;
            default:  
                $content = date("Y-m-d H:i:s",time())."\n你很优秀"."\n$object->Content";  
                break;  
        }//这部分也就是在识别用户发送的消息,比如用户发送“音乐”,系统自动回复最炫民族风。  
        if(is_array($content)){  
            if (isset($content[0]['PicUrl'])){  
                $result = $this->transmitNews($object, $content);  
            }else if (isset($content['MusicUrl'])){  
                $result = $this->transmitMusic($object, $content);  
            }  
        }else{  
            $result = $this->transmitText($object, $content);  
        }  
        return $result;  
    }  
  
    //接收图片消息  
    private function receiveImage($object)  
    {  
        $content = array("MediaId"=>$object->MediaId);  
        $result = $this->transmitImage($object, $content);  
        return $result;  
    }  
  
    //接收位置消息  
    private function receiveLocation($object)  
    {  
        $content = "你发送的是位置,纬度为:".$object->Location_X.";经度为:".$object->Location_Y.";缩放级别为:".$object->Scale.";位置为:".$object->Label;  
        $result = $this->transmitText($object, $content);  
        return $result;  
    }  
  
    //接收语音消息  
    private function receiveVoice($object)  
    {  
        if (isset($object->Recognition) && !empty($object->Recognition)){  
            $content = "你刚才说的是:".$object->Recognition;  
            $result = $this->transmitText($object, $content);  
        }else{  
            $content = array("MediaId"=>$object->MediaId);  
            $result = $this->transmitVoice($object, $content);  
        }  
  
        return $result;  
    }  
  
    //接收视频消息  
    private function receiveVideo($object)  
    {  
        $content = array("MediaId"=>$object->MediaId, "ThumbMediaId"=>$object->ThumbMediaId, "Title"=>"", "Description"=>"");  
        $result = $this->transmitVideo($object, $content);  
        return $result;  
    }  
  
    //接收链接消息  
    private function receiveLink($object)  
    {  
        $content = "你发送的是链接,标题为:".$object->Title.";内容为:".$object->Description.";链接地址为:".$object->Url;  
        $result = $this->transmitText($object, $content);  
        return $result;  
    }  
  
    //回复文本消息  
    private function transmitText($object, $content)      
    {  
        $textTpl = "<xml>  
        <ToUserName><![CDATA[%s]]></ToUserName>  
        <FromUserName><![CDATA[%s]]></FromUserName>  
        <CreateTime>%s</CreateTime>  
        <MsgType><![CDATA[text]]></MsgType>  
         <Content><![CDATA[%s]]></Content>  
        </xml>";  
          
        $result = sprintf($textTpl, $object->FromUserName, $object->ToUserName, time(),$content);  //格式化输出  
        return $result;  
    }  
  
    //回复图片消息  
    private function transmitImage($object, $imageArray)  
    {  
        $itemTpl = "<Image>  
            <MediaId><![CDATA[%s]]></MediaId>  
            </Image>";  
  
        $item_str = sprintf($itemTpl, $imageArray['MediaId']);  
  
        $textTpl = "<xml>  
         <ToUserName><![CDATA[%s]]></ToUserName>  
         <FromUserName><![CDATA[%s]]></FromUserName>  
         <CreateTime>%s</CreateTime>  
         <MsgType><![CDATA[image]]></MsgType>  
         $item_str  
         </xml>";  
  
        $result = sprintf($textTpl, $object->FromUserName, $object->ToUserName, time());  
        return $result;  
    }  
  
    //回复语音消息  
    private function transmitVoice($object, $voiceArray)  
    {  
        $itemTpl = "<Voice>  
        <MediaId><![CDATA[%s]]></MediaId>  
        </Voice>";  
  
        $item_str = sprintf($itemTpl, $voiceArray['MediaId']);  
  
        $textTpl = "<xml>  
    <ToUserName><![CDATA[%s]]></ToUserName>  
    <FromUserName><![CDATA[%s]]></FromUserName>  
    <CreateTime>%s</CreateTime>  
    <MsgType><![CDATA[voice]]></MsgType>  
    $item_str  
    </xml>";  
  
        $result = sprintf($textTpl, $object->FromUserName, $object->ToUserName, time());  
        return $result;  
    }  
  
    //回复视频消息  
    private function transmitVideo($object, $videoArray)  
    {  
        $itemTpl = "<Video>  
    <MediaId><![CDATA[%s]]></MediaId>  
    <ThumbMediaId><![CDATA[%s]]></ThumbMediaId>  
    <Title><![CDATA[%s]]></Title>  
    <Description><![CDATA[%s]]></Description>  
    </Video>";  
  
        $item_str = sprintf($itemTpl, $videoArray['MediaId'], $videoArray['ThumbMediaId'], $videoArray['Title'], $videoArray['Description']);  
  
        $textTpl = "<xml>  
         <ToUserName><![CDATA[%s]]></ToUserName>  
         <FromUserName><![CDATA[%s]]></FromUserName>  
         <CreateTime>%s</CreateTime>  
         <MsgType><![CDATA[video]]></MsgType>  
         $item_str  
         </xml>";  
  
        $result = sprintf($textTpl, $object->FromUserName, $object->ToUserName, time());  
        return $result;  
    }  
  
    //回复图文消息  
    private function transmitNews($object, $newsArray)  
    {  
        if(!is_array($newsArray)){  
            return;  
        }  
        $itemTpl = "    <item>  
        <Title><![CDATA[%s]]></Title>  
        <Description><![CDATA[%s]]></Description>  
        <PicUrl><![CDATA[%s]]></PicUrl>  
        <Url><![CDATA[%s]]></Url>  
    </item>  
";  
        $item_str = "";  
        foreach ($newsArray as $item){  
            $item_str .= sprintf($itemTpl, $item['Title'], $item['Description'], $item['PicUrl'], $item['Url']);  
        }  
        $newsTpl = "<xml>  
        <ToUserName><![CDATA[%s]]></ToUserName>  
        <FromUserName><![CDATA[%s]]></FromUserName>  
        <CreateTime>%s</CreateTime>  
        <MsgType><![CDATA[news]]></MsgType>  
        <Content><![CDATA[]]></Content>  
        <ArticleCount>%s</ArticleCount>  
        <Articles>  
        $item_str</Articles>  
        </xml>";  
  
        $result = sprintf($newsTpl, $object->FromUserName, $object->ToUserName, time(), count($newsArray));  
        return $result;  
    }  
  
    //回复音乐消息  
    private function transmitMusic($object, $musicArray)  
    {  
        $itemTpl = "<Music>  
    <Title><![CDATA[%s]]></Title>  
    <Description><![CDATA[%s]]></Description>  
    <MusicUrl><![CDATA[%s]]></MusicUrl>  
    <HQMusicUrl><![CDATA[%s]]></HQMusicUrl>  
         </Music>";  
  
        $item_str = sprintf($itemTpl, $musicArray['Title'], $musicArray['Description'], $musicArray['MusicUrl'], $musicArray['HQMusicUrl']);  
  
        $textTpl = "<xml>  
        <ToUserName><![CDATA[%s]]></ToUserName>  
        <FromUserName><![CDATA[%s]]></FromUserName>  
        <CreateTime>%s</CreateTime>  
        <MsgType><![CDATA[music]]></MsgType>  
        $item_str  
        </xml>";  
  
        $result = sprintf($textTpl, $object->FromUserName, $object->ToUserName, time());  
        return $result;  
    }  
  
    //日志记录  
    private function logger($log_content)  
    {  
        if(isset($_SERVER['HTTP_APPNAME'])){   //SAE  
            sae_set_display_errors(false);  
            sae_debug($log_content);  
            sae_set_display_errors(true);  
        }else if($_SERVER['REMOTE_ADDR'] != "127.0.0.1"){ //LOCAL  
            $max_size = 10000;  
            $log_filename = "log.xml";  
            if(file_exists($log_filename) and (abs(filesize($log_filename)) > $max_size)){unlink($log_filename);}  
            file_put_contents($log_filename, date('H:i:s')." ".$log_content."\r\n", FILE_APPEND);  
        }  
    }  
   
}  


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值