Hello,读者姥爷们,大家好。我是不是加多宝的宝,今天给大家带来 “微信公众平台-傻瓜入门教程” 的第二篇-事件篇。本篇主要讲述微信公众平台的事件是什么 和 我们如何处理微信公众平台给我们发来的事件消息。
什么是事件?
在微信用户和公众号产生交互的过程中,用户的某些操作会使得微信服务器通过事件推送的形式通知到开发者在开发者中心处设置的服务器地址,从而开发者可以获取到该信息。其中,某些事件推送在发生后,是允许开发者回复用户的,某些则不允许。
上面是《微信公众平台文档》给我们的解释。我们总结一下:
1.微信用户和公众号产生交互。(这是事件的发生条件)
2.微信服务器通过事件推送给我们设置的服务器地址。(这是事件发生后微信服务器做出的处理)
3.某些事件推送后,允许我们回复用户。(我们需要做出一定的处理,比如回复用户)
微信公众平台的事件有哪些?
1 关注/取消关注事件
2 扫描带参数二维码事件
3 上报地理位置事件
4 自定义菜单事件
5 点击菜单拉取消息时的事件推送
6 点击菜单跳转链接时的事件推送
这些是微信公众平台支持的事件类型。下面我们会拿关注事件(因为他允许我们回复用户)举例,来带大家了解如何处理事件。
首先我们先处理下我们上期的作业,将微信的服务器验证方法封装成到一个微信类中去:
Wechat.class.php文件
class Wechat{
private $token;//我们设置的token
private $appid;//微信给我们分配的appid在测试号管理页面上可以看到
private $appsecret;//同上
//构造方法
public function __construct($token,$appid,$appsecret){
$this->token = $token;
$this->appid = $appid;
$this->appsecret = $secret;//将三个参数复制给对象属性,方便我们以后使用
}/** * 微信验证,一般在配置服务器url时使用 * @params $nonce 微信get过来的随机数 * @params $timestamp 微信get活来的时间戳 * @params $signature 微信get过来的加密签名 * @params $echostr 微信get过来的随机字符串 */ public function verify($nonce,$timestamp,$signature,$echostr){ $tmpArr = array($token,$timestamp,$nonce); //字典序排序 sort($tmpArr,SORT_STRING); //拼接验证字符串 $tmpStr = implode('',$tmpArr); //sha1加密验证字符串 $tmpStr = sha1($tmpStr); //如果验证成功直接输出echostr并exit程序,否则输出error if($tmpStr == $signature){ echo $echostr; }else{ //todo错误日志 echo 'error'; } exit(); }
}
然后我们需要重新编写一下我们的test.php文件(我们在微信测试号管理里设置的服务器地址)
test.php文件
$token = 'rainlu';
$appid = 'wx7573a9d4c3809527';
$appsecret = '23258e25fe5f9ae6023258e25fe5f9ae60';//将这三项替换成自己
include('./Wechat.class.php');//引入我们的微信类
$wechat = new Wechat($token,$appid,$appsecret);
$wechat->verify($_GET['nonce'],$_GET['timestamp'],$_GET['signature'],$_GET['echostr']);//验证
然后再去测试号管理页面重新提交一下接口配置信息。
我们既然要响应事件,我们先接受微信服务器发来的消息
参考:《微信文档-接收消息》
当有事件发生时微信服务器会用post方法给我们发送一个xml格式的数据,由于不是我们php默认接受的post格式所有我们使用$_POST这个超全局静态变量是无法拿到的。这时候我们需要使用另一个超全局变量去接受没有被处理过的post数据:$_GLOBALS['HTTP_RAW_POST_DATA']
来接受数据,或则使用file_get_contents("php://input");
来接受。微信发送给我们的xml数据格式如下:
123456789
其中:
- ToUserName 指我们的微信公众号
- FromUserName 指用户的唯一标识,我们给用户回复消息会用到
- CreateTime 指消息的时间戳
- MsgType 指消息类型,event代表这是一个事件消息
- Event 指事件的名称,当MsgType为event时才会有,subscribe指这是一个订阅事件
好了我们直接上代码来接受消息吧。我们先修改我们的Wechat.class.php文件,为它添加一个获取post数据的方法
/**
* 获取post对象
*/
public function getPostObject(){
$postStr = file_get_contents("php://input");
return simplexml_load_string($postStr,'SimpleXMLElement',LIBXML_NOCDATA);
}
我们还需要回复给订阅我们微信公众号的用户一个信息,回复消息,实际上就是我们输出一个微信公众平台指定的xml格式的字符串而已,我们先回复用户一个最简单的文本消息,消息格式如下:
12345678
其中:
- ToUserName 指我们要回复的微信用户,就是我们上面讲到的微信服务器给我们发来的用户唯一标识
- FromUserName 指我们的微信公众号
- CreateTime 指消息的时间戳
- MsgType 指我们回复的消息类型
- Content 指我们回复的内容。
那我们还需要给Wechat.class.php中添加一个获取回复消息xml字符串的方法,首先我们将上面的回复xml格式字符串做成模板,然后用sprintf方法来替换模板中的%s。(参考《php手册-sprintf函数》),方法代码如下:
/*
* 获取一个文本消息的xml字符串
* @params $to 发送的目标用户
* @params $from 发送者
* @params $time 发送时间戳
* @params $content 发送内容
* @return XML String 文本消息的xml字符串
*/
public function getTextMsg($to,$from,$time,$content){
$tpl = '';
%s
return sprintf($tpl,$to,$$from,$time,$content);
}
由于我们的数据是xml格式的,我们需要将它转化为一个对象,方便我们使用php来获取里面的数据。使用上面的simplexml_load_string函数。(详细见《php手册》)
然后修改我们的test.php调用这个方法来接受对象,然后处理订阅事件消息
$token = 'rainlu';
$appid = 'wx7573a9d4c3809527';
$appsecret = '23258e25fe5f9ae6023258e25fe5f9ae60';//将这三项替换成自己
include('./Wechat.class.php');//引入我们的微信类
$wechat = new Wechat($token,$appid,$appsecret);
//$wechat->verify($_GET['nonce'],$_GET['timestamp'],$_GET['signature'],$_GET['echostr']);//验证完成,可以注释或则删除
$postObj = $wechat->getPostObject();//调用我们上面写的方法来获取 消息对象
if(empty($post)){
echo "nothing";
exit;
}
$he = $post->FromUserName;//与我们发生事件的用户
$me = $post->ToUserName;//我们自己的公众号
$msgType = $post->MsgType;//消息类型
//判断消息类型 实例化处理器类(两个处理类在下面书写)
switch($msgType){
case 'event'://判断是否为事件消息
$handle = new HandleEvent();//定义的处理事件消息类
$handle->handle($post ,$he ,$me ,$wechat);//处理方法
break;
default ://如果为普通消息走这里
$handle = new HandleMsg();//定义的处理普通消息类
$handle->handle($post ,$he ,$me ,$wechat);//处理方法
}
//下面我们先定义一个普通消息处理类,我们这一篇先不写
class HandleMsg{
/**
* 处理事件消息
* @params $post post对象
* @params $he 产生该事件的用户
* @params $me 我
* @params $wechat 微信处理对象
*/
public function handle($post ,$he ,$me ,$wechat){}//什么都没有,不处理。。
}
//下面是我们的事件处理类了
/**
* 事件消息处理类,处理完后exit
*/
class HandleEvent{
/**
* 处理事件消息
* @params $post post对象
* @params $he 产生该事件的用户
* @params $me 我
*/
public function handle($post ,$he ,$me ,$wechat){
switch($post->Event){
case 'subscribe'://如果是订阅事件,交给我们的订阅处理方法来处理
$this->subscribe($he ,$me ,$wechat);
break;
}
}
/**
* 处理订阅事件
*/
private function subscribe($he,$me,$wechat){
$content = '欢迎订阅我们的微信公众号,have fun~';
echo $wechat->getTextMsg($he ,$me ,time() ,$content);//调用我们上面写的获取一个回复消息的xml字符串的方法并输出
exit;
}
}
接下来,把新写的代码放到服务器上。然后,扫一扫关注我们的微信测试号,你就会发现。公众号会给我们发送一条消息~
这一篇到这里就结束了,喜欢的话点个赞啊,投个硬币(并不)啊都可以。
参考文献: 《微信官方文档》 , 《php官方手册》
谨记512,为同胞默哀。转载请注明出处。by 2016-05-12 over。