当我们成功接入微信的公众平台后,就会收到微信推送给我们服务器的消息了。消息主要包括:
1. 用户关注或者取消关注时,微信的推送消息。
2. 用户主动发的上行的消息推送,此时,我们可以处理消息。比如,根据用户所发消息的关键词,触发我们的自动回复。
3. 自定义菜单消息等。
消息模型
事件推送消息
在本文中,我们首先要处理用户关注和取消关注的事件推送消息。这些消息,可以让我们记录用户的关系,统计和分析用户,标识用户。
微信推送的消息,都是post请求到我们申请的URL上的。可以根据MsgType来表示出消息类型,针对不同的消息类型,分别做处理。
在这里,我们可以用一个统一的入口来接受消息,解析消息,然后根据消息类型,实例化不同的消息对象,来进行处理。
核心代码如下:
$postStr = $GLOBALS["HTTP_RAW_POST_DATA"]; if (!empty($postStr)){ $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA); $type = $postObj->MsgType; // 根据不同的消息类型初始化对象 $instance = MsgController::factory($type); $instance->processMsg($postObj) ; }
在这里,我们使用了工厂模式。MsgController 核心代码如下:
public static function factory($type = '') { if (strtolower($type) == 'text') { return new TextMsg(); } elseif (strtolower($type) == 'event') { return new EventMsg(); } }
如果有用户关注,那我们会在EventMsg里处理消息。
<?php class EventMsg{ public function processMsg($postObj) { // 用户的openid,在同一应用下,可以作为用户的唯一标识 $fromUsername = $postObj->FromUserName; $toUsername = $postObj->ToUserName; // 事件类型:订阅,取消订阅,自定义菜单点击等。 $event = trim($postObj->Event); // 不同的事件,调用不同的处理函数 call_user_func_array(array("EventMsg", $event), array($fromUsername)); } private function subscribe($openid) { // 在这里我们记录用户 // 这里我省略处理... // 当用户关注我们的时候,我们可以发送一条关注消息 $textMsg = MsgController::factory(MsgController::MESSAGE_TYPE_TEXT); $msg = '感谢你的关注'; $textMsg->send($msg, WEIXINID, $openid); } }
从上面看到,针对不同的事件类型,我们会用不同的函数进行处理。在这里,碰到了技术问题,如果$event赋值的时候没有进行trim处理,如下所示:
$event = $postObj->Event call_user_func_array(array("EventMsg", $event), array($fromUsername));
这样会造成系统报错,call_user_func_array() expects parameter 1 to be a valid callback, second array member is not a valid method in /data/www/weixin/EventMsg.php on line 17
但是加上trim函数或者call_user_func_array(array("EventMsg", “$event”), array($fromUsername));就可以,这里没想明白。
在subscribe函数里,我可以记录用户的openid,也可以发送一条关注消息。同理,我们也可以定义unsubscribe函数。发消息的函数如下:
/** * send * 文本消息的发送 * * @param mixed $msg 消息内容 * @param mixed $wxid 开发者的微信号 * @param mixed $openid 用户的openid * @access public * @return void */ public function send($msg, $wxid, $openid) { $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, $openid, $wxid, time(), self::MESSAGE_TYPE, $msg); echo $resultStr; }
当我们回复消息时,微信规定最多不要超过5秒。当然,回复各种类型的消息都可以,图片,图文等。
====================