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