# 1.模块目录
![](https://box.kancloud.cn/d7bdcb1da00dede47740893362944e54_218x211.png)
# 2.消息处理流程
Api.php $engine = new WeEngine();$engine->start();
$message = $this->account->parse($postStr);
WeUtility::logging('trace', $message);
输出结果:
2016-06-07 14:27:25 trace :
------------
Array:
from : fromUser ;
to : toUser ;
time : 1465280845 ;
type : event ;
event : subscribe ;
tousername : toUser ;
fromusername : fromUser ;
createtime : 1465280845 ;
msgtype : event ;
eventkey : ;
msgid : 1234567890123456 ;
$pars = $this->analyze($message); private function analyze(&$message)
1)in_array($message['type'], array('event', 'qr')(事件或者扫码消息)call_user_func_array(array($this, 'analyze' . $message['type']), array(&$message));
2)method_exists($this, 'analyze' . $message['type']) (默认调取analyze+消息类型的方法)
$response = $this->process($par); private function process($param)
$processor = WeUtility::createModuleProcessor($param['module']);
(account.class.php里的createModuleProcessor()根据module名称查询)
public static function createModuleProcessor($name)
//拼装模块处理类名
$classname = "{$name}ModuleProcessor";
1)if(!class_exists($classname)) { 不存在模块的类,直接加载插件里面的processor.php中的类声明
$file = IA_ROOT . "/addons/{$name}/processor.php"
if(!is_file($file)) {
$file = IA_ROOT . "/framework/builtin/{$name}/processor.php";
}
2)$o = new $classname();
load()->model('module');
$o->module = module_fetch($name);//module.mod.php module_fetch() 获取当前公号下安装好的指定模块及模块信息
$o->__define = $file;
self::defineConst($o);
if($o instanceof WeModule) {
return $o;
}
$response = $processor->respond(); //执行具体的模块的processor.处理逻辑
例如CoverModuleProcessor类的处理逻辑
class CoverModuleProcessor extends WeModuleProcessor {
public function respond() {
global $_W;
$content = $this->message['content'];
//查询回复表中的id对应的回复内容
$reply = pdo_fetch('SELECT * FROM ' . tablename('cover_reply') . ' WHERE `rid`=:rid', array(':rid' => $this->rule));
if(!empty($reply)) {
load()->model('module');
$module = module_fetch($reply['module']);
if (empty($module) && !in_array($reply['module'], array('site', 'mc', 'card'))) {
return '';
}
$url = $reply['url'];
if(empty($reply['url'])) {
$entry = pdo_fetch("SELECT eid FROM ".tablename('modules_bindings')." WHERE module = :module AND do = :do", array(':module' => $reply['module'], ':do' => $reply['do']));
$url = url('entry', array('eid' => $entry['eid']));
}
if (!strexists($url, '&j=') && !empty($_W['acid'])) {
$url = str_replace("?i={$_W['uniacid']}&", "?i={$_W['uniacid']}&j={$_W['acid']}&", $url);
}
$news = array();
$news[] = array(
'title' => $reply['title'],
'description' => $reply['description'],
'picurl' => $reply['thumb'],
'url' => $url
);
return $this->respNews($news);
}
return '';
}
if($this->isValidResponse($response)) {
$hitParam = $par;
if(!empty($par['keyword'])) {
$hitKeyword = $par['keyword'];
}
break;
}
WeUtility::logging('params', $hitParam);
2016-06-07 14:27:25 params :
------------
Array:
message : Array ;
module : cover ;
rule : 32 ;
priority : 0 ;
keyword : Array ;
WeUtility::logging('response', $response);
2016-06-07 14:27:25 response :
------------
Array:
FromUserName : toUser ;
ToUserName : fromUser ;
MsgType : news ;
ArticleCount : 1 ;
Articles : Array ;
$resp = $this->account->response($response);
$resp = $this->clip($resp, $hitParam);
if(!empty($_GET['encrypt_type']) && $_GET['encrypt_type'] == 'aes') {
$resp = $this->account->encryptMsg($resp);
$resp = $this->account->xmlDetract($resp);
}
echo $resp;
$this->receive($hitParam, $hitKeyword, $response);
private function receive($par, $keyword, $response) {
if (in_array($this->message['event'], array('subscribe', 'unsubscribe')) || in_array($this->message['type'], array('subscribe', 'unsubscribe'))) {
if (in_array($this->message['event'], array('subscribe', 'unsubscribe')) || in_array($this->message['type'], array('subscribe', 'unsubscribe'))) {
$modules = uni_modules();
$core = array();
$core['name'] = 'core';
$core['subscribes'] = array('core');
array_unshift($modules, $core);
foreach($modules as $m) {
if(!empty($m['subscribes'])) {
if ($m['name'] == 'core' || in_array($this->message['type'], $m['subscribes'])
|| in_array($this->message['event'], $m['subscribes'])) {
$obj = WeUtility::createModuleReceiver($m['name']);
$obj->message = $this->message;
$obj->params = $par;
$obj->response = $response;
$obj->keyword = $keyword;
$obj->module = $m;
$obj->uniacid = $_W['uniacid'];
$obj->acid = $_W['acid'];
if(method_exists($obj, 'receive')) {
@$obj->receive();
}
}
}
}
} else {
$row = array();
$row['uniacid'] = $_W['uniacid'];
$row['acid'] = $_W['acid'];
$row['dateline'] = $par['message']['time'];
$row['message'] = iserializer($par['message']);
$row['keyword'] = iserializer($keyword);
unset($par['message']);
unset($par['keyword']);
$row['params'] = iserializer($par);
$row['response'] = iserializer($response);
$row['module'] = $par['module'];
$row['type'] = 1;
pdo_insert('core_queue', $row);
}
}
数据表的查询:
Ims_Rule(关键词回复规则表),加载module+processor.php文件时,查询的就是IMS_Rule这个表
# 3.视图页
display.html
# 4.文本
消息类型同公众平台官方不同之处在于将 event 类型拆分开为独立的消息类型, 避免了重复判断.
根据消息类型不同, 消息对象结构还存在不同的附加数据,按照类型定义如下:
文本消息
粉丝用户向公众号发送了一条普通文本消息(包括包含表情的消息, 或者纯表情消息)
处理文本消息可以实现简单的文本对话, 结合使用文本上下文(请参阅上下文处理)可以实现调查, 测试等复杂的交互.
$text_message = array(
// 全局数据
'tousername' => 'toUser'
'fromusername' => 'fromUser'
'createtime' => '123456789'
'msgtype' => 'text' // string: 消息类型
'content' => // string: 文本消息内容
'redirection' => false, // bool: 是否是重定向
'source' => null // string: 消息来源, 消息二次分析(目前来源:qr,click, 将扫码等事件转换为 text 事件.)
)