PHP微信定制开发-消息的识别和消息工具类的封装

对于消息管理,服务器被动回复消息是比较重要且需要好好掌握的知识点,在这个模块中我们需要接收到用户发送过来的消息,并识别出消息类型,最后把识别结果以文本消息的形式响应给用户,下面是文档地址

https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140453

从文档中我们可以看出通过MsgType来判断消息类型,通过Content取得发送过来的消息(仅文本),为了把消息响应给用户方便开发我们需要先写一个工具类用来处理消息,因消息体的格式比较统一,这里的工具类封装对于xml选用最简单的方式,类似simplexml就不适用了,有兴趣的自己尝试

一 消息工具类的封装

<?php
namespace  util;


define("TEXTMESSAGE","text");
define("NEWSMESSAGE","news");

/** 消息工具类
 * @author chenwill2
 *
 */
class MessageUtil{
    
    /** 生成文本消息字符串
     * @param $toUserName
     * @param $fromUserName
     * @param $content
     * @return string
     */
    function textMessageToXml($toUserName,$fromUserName,$content="你发送的是文本消息"){
        $textTpl = "<xml>
                        <ToUserName><![CDATA[%s]]></ToUserName>
                        <FromUserName><![CDATA[%s]]></FromUserName>
                        <CreateTime>%s</CreateTime>
                        <MsgType><![CDATA[%s]]></MsgType>
                        <Content><![CDATA[%s]]></Content>
                        <FuncFlag>0</FuncFlag>
                        </xml>";
        $resultStr=sprintf($textTpl,$toUserName,$fromUserName,time(),TEXTMESSAGE,$content);
       
        return $resultStr;
    }
    
    /** 生成图文消息字符串
     * @param $toUserName
     * @param $fromUserName
     * @param $article
     * @return string
     */
    function articleMessageToXml($toUserName,$fromUserName,$article){
        $childArticle="";
        foreach ($article as $item){
            $child="<item>
                        <Title><![CDATA[%s]]></Title> 
                        <Description><![CDATA[%s]]></Description>
                        <PicUrl><![CDATA[%s]]></PicUrl>
                        <Url><![CDATA[%s]]></Url>
                     </item>";
            $childInfo=sprintf($child,$item["title"],$item["description"],$item["picurl"],$item["url"]);
            $childArticle.=$childInfo;
        }
        
        $textTpl = "<xml>
                       <ToUserName><![CDATA[%s]]></ToUserName>
                       <FromUserName><![CDATA[%s]]></FromUserName>
                       <CreateTime>%s</CreateTime>
                       <MsgType><![CDATA[%s]]></MsgType>
                       <ArticleCount>%s</ArticleCount>
                       <Articles>
                          $childArticle
                        </Articles>
                      </xml>";
                          
        $resultStr=sprintf($textTpl,$toUserName,$fromUserName,time(),NEWSMESSAGE,count($article));
      
        return $resultStr;
    }
   
}

?>

这里只封装了2种比较常用的消息分别是文本消息、图文消息;其他的如有需要可以自己编写,反正封装方式都差不多

二  消息类型识别并回复类型结果给用户

<?php
namespace handler;

include_once __DIR__.DIRECTORY_SEPARATOR."util".DIRECTORY_SEPARATOR."MessageUtil.php";


define("TOKEN", "weixinCourse");

// 1 判断请求方法,get请求一般为消息验证,post为其他消息交互
// 2 验证signature是否正确(消息来自微信服务器)
$handler = new \handler\WeixinHandler();

$reqMethod = strtolower($_SERVER["REQUEST_METHOD"]);
if ("get" == $reqMethod && !empty($_GET["echostr"])) {
    if ($handler->isValid()) {
        $echostr = $_GET["echostr"];
        echo $echostr;
        exit();
    }
} else {
    //判断消息类型,返回"你发送的是xxx消息"
    $handler->responseMessage();
}

class WeixinHandler
{

    function checkSignature()
    {
        $timestamp = $_GET["timestamp"];
        $nonce = $_GET["nonce"];

        $tmpArr = array(
            TOKEN,
            $timestamp,
            $nonce
        );
        sort($tmpArr, SORT_STRING);
        $tmpStr = implode($tmpArr);
        $tmpStr = sha1($tmpStr);

        if ($tmpStr) {
            return $tmpStr;
        } else {
            return "";
        }
    }

    function isValid()
    {
        $signature = $_GET["signature"];
        if ($signature == $this->checkSignature()) {
            return true;
        } else {
            return false;
        }
    }
    function responseMessage(){
        $msgUtil = new \util\MessageUtil();
        $defaultMsgType="text";
        //从请求数据获取FromUserName和ToUserName以及消息类型
        $postStr = isset($GLOBALS['HTTP_RAW_POST_DATA']) ? $GLOBALS['HTTP_RAW_POST_DATA'] : file_get_contents("php://input");
        
        if(!empty($postStr)){
            $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
            //发送方账号(openId)
            $fromUsername = $postObj->FromUserName;
            //开发者微信号
            $toUsername = $postObj->ToUserName;
            //消息类型
            $MsgType = strtolower($postObj->MsgType);
            //消息内容
            $keyword = trim($postObj->Content);
          
            
            $msgUtil = new \util\MessageUtil();
            $typeResult="";
            $resultStr="";
           
            if("text"==$MsgType){
               $typeResult="你发送的是文本消息";
            }else if("image"==$MsgType){
                $typeResult="你发送的是图片消息";
            }else if("voice"==$MsgType){
                $typeResult="你发送的是语音消息";
            }else if("video"==$MsgType){
                $typeResult="你发送的是视频消息";
            }else if("shortvideo"==$MsgType){
                $typeResult="你发送的是短视频消息";
            }else if("location"==$MsgType){
                $typeResult="你发送的是地理位置消息";
            }else if("link"==$MsgType){
                $typeResult="你发送的是链接消息";
            }else if("event"==$MsgType){
                //事件推送处理
                $typeResult="事件推送消息";
            }else{
                $typeResult="你发送的是其他类型的消息";
            }
            
            if("text"==$defaultMsgType){
                $resultStr=$msgUtil->textMessageToXml($fromUsername, $toUsername,$typeResult);
            }
           
            echo $resultStr;
           
        }else{
           echo "";
           exit;
       }
    
    }
}

?>

需要注意的是如果使用名称空间,new一个类的时候要注意带上名称空间,否则会出现错误

 

到此为止微信就能正常响应消息给用户了,对于事件推送这里没有做详细区分,后面会针对这块分享几篇博客给大家,下次分享的内容是 微信菜单接口和微信根据城市调用百度API查天气预报的小例子

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值