1. 将消息转换为对象
微信服务器将用户消息转发到开发服务器之后,我们首先要做的时读取消息,然后根据消息类型和内容做出回复
首先获取消息
下面代码能够获取以post方式提交过来的xml数据
$xml = file_get_contents('php://input');
但是获取的数据是字符串类型,处理起来非常不方便,使用下面的方法将其转换为对象
$request = simplexml_load_string($xml);
转换之后,就可以使用对象->属性 的方式从对象中获取数据类
举例说明:
如用户向订阅号发送的是一个文本消息,消息内容为“你好”,按照上一章所讲的文本消息结构,微信服务器会将消息封装成如下的xml格式,然后才发送给开发服务器,也就是我们上面的index方法
<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>1348831860</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[你好]]></Content>
<MsgId>1234567890123456</MsgId>
</xml>
我们使用simplexml_load_string 将其转换成对象后,就可以使用下面的方式获取 content 中的内容了
$requesst->Content
其他内容的获取也是这种方式,但又两点需要注意
- 区分大小写
- MsgType 用来区分消息类型,如文本消息=text,图片消息=image,事件推送消息=event
2. 处理消息
获取到消息后,可以将消息保存到数据库,或者直接予以回复
我们这里说一下回复消息
具体的可以回复消息的类型,参见如下地址
https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140543
我们这里以回复文本消息为例,比如想要回复“hello”,则需要拼接成如下的xml结构,才可以回复
<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>12345678</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[hello]]></Content>
</xml>
完整代码如下所示
public function index()
{
if (isset($_GET['echostr'])) {
//接收微信服务器发送过来的数据
$signature = $_GET['signature'];
$timestamp = $_GET['timestamp'];
$nonce = $_GET['nonce'];
//这里token的值应该与配置中的token值一致
$token = "weixin";
//1)将token、timestamp、nonce三个参数进行字典序排序
$arr = array($token, $timestamp, $nonce);
sort($arr);
//2)将三个参数字符串拼接成一个字符串进行sha1加密
$tempstr = implode('', $arr);
$tempstr = sha1($tempstr);
//3)开发者获得加密后的字符串可与signature对比,标识该请求来源于微信
if ($tempstr == $signature) {
//一定要加上这行代码,否则可能导致token总是验证失败
ob_clean();
//4) 返回微信服务器发送过来的 echostr 的值
echo $_GET['echostr'];
}
exit();
} else {
$xml = file_get_contents('php://input');
//file_put_contents(ROOT_PATH.'public/aa.txt',$xml);
//将xml文本转换为对象
$request = simplexml_load_string($xml);
$text = "<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[%s]]></Content>
</xml>";
$info = sprintf($text, $request->FromUserName, $request->ToUserName, time(), 'hello');
echo $info;
}
}
上面的代码很混乱,我们将其拆分成几个方法,就会精简很多
第一步,定义方法,用来回复消息。
//处理用户的请求
public function responseMsg()
{
//获取用户提交的数据(数据是以post方式提交的)
$xml = file_get_contents('php://input');
//file_put_contents(ROOT_PATH.'public/aa.txt',$xml);
//将xml文本转换为对象
$request = simplexml_load_string($xml);
switch ($request->MsgType) {
case "event":
//处理事件消息
break;
case "text":
//处理文本消息
$this->doText($request,'hello');
break;
}
}
方法解释:
- 根据MsgType判断消息类型
- 如果消息类型为text,也就是说用户发送的是文本消息,就回复一条文本消息
第二步:编写 doText 方法,专门用来回复文本消息
public function doText($request, $content)
{
$text = "<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[%s]]></Content>
</xml>";
$info = sprintf($text, $request->FromUserName, $request->ToUserName, time(), $content);
file_put_contents(ROOT_PATH . 'public/aa.txt', $info);
echo $info;
}
第三步:修改 index 方法代码,再 else 中调用 responseMsg 方法
public function index()
{
if (isset($_GET['echostr'])) {
//接收微信服务器发送过来的数据
$signature = $_GET['signature'];
$timestamp = $_GET['timestamp'];
$nonce = $_GET['nonce'];
//这里token的值应该与配置中的token值一致
$token = "weixin";
//1)将token、timestamp、nonce三个参数进行字典序排序
$arr = array($token, $timestamp, $nonce);
sort($arr);
//2)将三个参数字符串拼接成一个字符串进行sha1加密
$tempstr = implode('', $arr);
$tempstr = sha1($tempstr);
//3)开发者获得加密后的字符串可与signature对比,标识该请求来源于微信
if ($tempstr == $signature) {
//一定要加上这行代码,否则可能导致token总是验证失败
ob_clean();
//4) 返回微信服务器发送过来的 echostr 的值
echo $_GET['echostr'];
}
exit();
} else {
$this->responseMsg();
}
}
好了,下面可以使用自己的微信关注自己的订阅号,然后发送一个文本消息,看看能不能得到回复