首先对微擎的工做原理作简单描述, 微擎使用规则和模块的机制来处理公众平台的请求数据并返回响应的结果.php 执行流程描述为: 粉丝用户与公众号码进行对话或交互, 然后公众平台将粉丝用户的请求消息(当前包括: 文本, 图片, 位置, 连接, 事件. 请参阅消息类型)传递给微擎系统, 微擎系统按照消息类型和对应的公众号所设定的规则列表匹配到合适的规则(请参阅消息路由), 规则定义中包括处理此消息所使用的模块和此模块处理消息时所须要的其余附加数据(请参阅模块定义), 然后模块将会按照请求的消息数据和模块附加数据进行相关业务处理并返回处理结果(请参阅响应类型), 微擎系统将处理结果返回给公众平台, 然后经公众平台返回给粉丝用户.html 微擎的主处理流程实现定义于: engine.php 中, 若有须要请参阅源码.正则表达式 消息类型消息类型指粉丝用户经过公众平台与微擎进行交互时所提供的消息数据的类型. 消息类型基于微信公众平台提供的数据接口, 微擎在其基础上进行包装处理, 方便PHP开发者进行业务处理. 保存消息的基本对象结构定义为:编程 $message => array( 'from' => '', //string: 发送消息方, 表明一个粉丝用户(使用OpenID表示) 'to' => '', //string: 消息接收方, 对应当前的公众号(使用OpenID表示) 'time' => '', //int: 消息发送时间, 使用Unix时间戳表示 'type' => '', //string: 消息类型, 用于区分不一样类型的消息, 请参阅下文 'msgid' => '' //int: 消息ID, 公众平台系统用于惟一标识一条请求消息 ); 消息类型同公众平台官方不一样之处在于将event类型拆分开为独立的消息类型, 避免了重复判断. 根据消息类型不一样, 消息对象结构还存在不一样的附加数据, 按照类型定义以下:微信
$message => array( //....全局数据 'type' => 'text', //string: 表明当前消息为文本消息 'content' => '' //string: 文本消息内容 );
$message => array( //....全局数据 'type' => 'image', //string: 表明当前消息为图片消息 'url' => 'http://same.im/image.jpg' //string: 用户所发送的图片地址 );
$message => array( //....全局数据 'type' => 'location', //string: 表明当前消息为位置消息 'location_x' => '', //float: 表明位置经度 'location_y' => '', //float: 表明位置纬度 'scale' => '', //int: 表示地图缩放倍数 'label' => '' //float: 表示地点描述 );
$message => array( //....全局数据 'type' => 'link', //string: 表明当前消息为连接消息 'title' => '', //float: 表明连接标题 'description' => '', //float: 表明连接描述信息 'scale' => 'url' //int: 表示连接的URL );
$message => array( //....全局数据 'type' => 'subscribe' //string: 表明当前消息为关注消息 );
$message => array( //....全局数据 'type' => 'unsubscribe' //string: 表明当前消息为取消关注消息 );
$message => array( //....全局数据 'type' => 'CLICK', //string: 表明当前消息为菜单点击消息 'eventkey' => '' //string: 菜单点击附加的菜单数据信息 ); 消息路由消息路由是指粉丝用户经公众平台发送消息内容至微擎时, 微擎系统查找对应的规则记录, 并将消息分配至合适的模块处理的过程. 微擎系统按照不一样的消息类型, 进行不一样的处理. 处理方式以下:
'
* 关键字包含 指粉丝用户发送的消息内容含有指定的关键字就指派到特定规则. * 内容等价 指粉丝用户发送的消息内容彻底等于指定的内容才指派到特定规则. * 正则表达式 指粉丝用户发送的消息类型符合指定正则表达式定义的模式时指派到特定规则.(高级模式, 须要有编程经验)
模块定义上下文处理微擎现已支持上下文锁定对话, 能够将粉丝用户的对话锁定至特定模块. 用以实如今线调查, 在线测试等相似的功能. 微擎的上下文操做使用 $_SESSION + DB 来实现.上下文数据保存在$_SESSION['context']变量中,并与sessions表中数据作一对一的映射,用户可经过操做sessions表中的数据进行上下文会话的基本管理. 要实现上下文操做主要使用 Processor 里的内定方法:
class BloodTestModuleProcessor extends WeModuleProcessor { //void: 全部处理程序必须实现虚函数 respond. 用以响应消息 public function respond() { if(!$this->inContext) { $reply = '请输入你的血型(A, B, O, AB), 来分析你今年的运程. '; $this->beginContext(); // 若是是按照规则触发到本模块, 那么先输出提示问题语句, 并启动上下文来锁定会话, 以保证下次回复依然执行到本模块 } else { $btypes = array('a', 'b', 'o', 'ab'); $b = strtolower($this->message['content']); // 若是当前会话在上下文中, 那么表示当前回复是用户回答提示问题的答案. if(in_array($b, $btypes)) { switch($b) { case 'a': $reply = 'A型血今年.....'; break; case 'b': $reply = 'B型血今年.....'; break; case 'o': $reply = 'O型血今年.....'; break; case 'ab': $reply = 'AB型血今年.....'; break; } $this->endContext(); // 若是当前回答符合答案格式, 那么进行保存并进行下一个问题. (能够保存至 SESSION 中) // 直到最后一个问题回答完成, 输出测试结果给用户, 并结束对话锁定. 以保证用户其余对话能正常路由. // 本示例只有一个问题, 所以不保存答案, 直接输出测试结果. // 若是对话默认的超时不够, 那么能够在每次提出下一个问题的时候从新调用 beginContext 来顺延超时. } else { $reply = '请输入正确的血型(A, B, O, AB). '; // 回答不符合答案格式, 那么从新显示当前问题. } } return $this->respText($reply); // 返回至系统 } private function respText($content) { $response = array(); $response['FromUserName'] = $this->message['to']; $response['ToUserName'] = $this->message['from']; $response['MsgType'] = 'text'; $response['Content'] = htmlspecialchars_decode($content); return $response; } } |