在2次开发中,涉及到比较多的也比较繁琐的就是服务器和微信服务器的交互
用户在公众号里操作回复关键词都会让微信服务器和开发者的服务器进行交互
用户一旦关注了某某公众号--微信后台会去查询该公众号是否连接了2次开发平台--吧关注事件发送到我们服务器上
在微擎里api.php肩负这1核心使命
当微信服务器请求开发者服务器上api.php的时候
查找到所有模块对象,根据传递的ID找到查找对应的微信账户(在我们平台绑定的)
微擎首先会建立核心引擎对象
$engine = new WeEngine();
执行start()函数
1:如果该公众号在我们平台没有对应的账户exit('Miss Account.');
2:根据微信平台传递来的参数和平台绑定的token进行校验($this->account->checkSign()) 检测失败 exit('Check Sign Fail.');
3:检测平台的请求方式,如果成功 执行到这行说明账户绑定成功 则更新账户状态 我们可以在后台发现绑定成功几个字
4:微信交互信息都用post形式推送XML数据到我们服务器
判断是否采用加密通信 如果加密先解密,如果WeAccount来解析交互的XML信息
原始文本交互信息如下:
通过微擎解析成
Array ( [from] => 发送人的微信账户加密即openid [to] => 公众平台的账户 [time] => 1447661567 [type] => text [event] => [tousername] => 公众平台的账户 [fromusername] => 发送人的微信账户加密即openid [createtime] => 1447661567 [msgtype] => text [content] => 关键词 [msgid] => 消息id [redirection] => [source] => )
5:微擎开始封装全局变量
$_W['openid'] = $message['from'];
$_W['fans'] = array('from_user' => $_W['openid']);
6:开始操作会员和粉丝表
$this->booking($message);
根据接受到的openid去查询会员粉丝表:用来判断是否是我们的粉丝
如果是我们的粉丝
6. 1:如果粉丝字段follow非空 则判断当前的事件即$message['event']
如果是取消关注则修改字段follow为0. 一些列其他相关
如果是其他事件说明用户正在使用我们平台交互 follow为1所以粉丝的follow可以识别用户是否关注(服务号正常用,订阅号在网页中无法获取openid不要用这个功能去查询是否关注)
获取粉丝表的UID,该字段管理会员信息表使用这个外键的意识是粉丝表的数据长久不变 会员可以无限制修改自己的信息 但是一旦会员信息被修改要如何查找到这个修改信息以后的会员?就依靠这个不变化的粉丝表的uid了,通过交互产生的OPENID查找到粉丝表对应的数据,再根据这个不变的外键查找到对应经常变化会员表的信息
如果没查询到会员则判断是否开启强制注册 如果强制注册则自动注册会员
然后再用返回的会员主键更新粉丝表UID
如果不是我们的粉丝
6.2则自动注册粉丝和会员 逻辑同6.1
7:如果是取消关注事件 则不用进行其他的逻辑处理 直接调用
$this->receive($hitParam, $hitKeyword, $response);
7.1 该函数用于查询所有模块查看所有模块的subscribes是否有配置相关标签
即我们在模块里写的manifest.xml里的
如果配置过事件则会去对应模块下查询recevier.php如果查询不到获取系统默认目录
/framework/builtin/模块名字/ 查询recevier.php
构建receiver对象
然后吧交互的XML信息 即被封装的meesage信息封装到了该对象的message中
同样被封装的还有传递的3个参数和相关全局变量$_W[uniacid]
去执行该对象的recevier()方法
所以我们可以在recevier.php里轻松使用$this->message来操作微信交互数据
8:开始操作session 微擎自定义的session被存入了数据库 不再操作文件IO这样会提高session操作效率
session_set_save_handler(
array(&$sess, 'open'),//在运行session_start()时执行
array(&$sess, 'close'),//在脚本执行完成或调用session_write_close() 或 session_destroy()时被执行,即在所有session操作完后被执行
array(&$sess, 'read'),//在运行session_start()时执行,因为在session_start时,会去read当前session数据
array(&$sess, 'write'), //此方法在脚本结束和使用session_write_close()强制提交SESSION数据时执行
array(&$sess, 'destroy'),//在运行session_destroy()时执行
array(&$sess, 'gc') //执行概率由session.gc_probability 和 session.gc_divisor的值决定,时机是在open,read之后,session_start会相继执行open,read和gc
);
9:开始解析数据$this->analyze($message);
该函数的作用是用来根据关键词查询到具体的模块信息,封装了关键词 模块名字 微信交互信息等属性
10:遍历第9步匹配到的数据(此数据是按照回复规则ID逆序 查询到所有的回复规则匹配数据 即用正则或字符串包含来判断当前关键词是否在message[content]中),
再遍历的过程中执行处理响应功能 即 process
该方法会去模块下寻找processor.php找不到同recevier.php处理过程一样,同时该对象的封装的属性同recevier.php的实现类对象封装的属性
在对应的pocessor.php中调用process方法来处理响应信息
该类是WeModuleProcessor类的子类 WeModuleProcessor类封装了大量处理响应的方法最常见的就是
respNews
该函数接受数组对象最多可以传递10个数组 作为多个图文信息
11:
通过处理响应函数可以得到1个响应相关的数组对象
Array
(
[FromUserName] =>
[ToUserName] =>
[MsgType] => news
[ArticleCount] => 1
[Articles] => Array
(
[0] => Array
(
[Title] => 关键词标题173
[Description] => 22222
[PicUrl] => 具体图片网址
[Url] => 网页连接地址
[TagName] => item
)
)
)
通过$resp = $this->account->response($response);
来转成XML数据响应给腾讯服务器