在2次開發中,涉及到比較多的也比較繁瑣的就是服務器和微信服務器的交互php
用戶在公衆號裏操做回覆關鍵詞都會讓微信服務器和開發者的服務器進行交互數據庫
用戶一旦關注了某某公衆號--微信後臺會去查詢該公衆號是否鏈接了2次開發平臺--吧關注事件發送到咱們服務器上api
在微擎裏api.php肩負這1核心使命數組
當微信服務器請求開發者服務器上api.php的時候服務器
查找到全部模塊對象,根據傳遞的ID找到查找對應的微信帳戶(在咱們平臺綁定的)
微信
微擎首先會創建核心引擎對象session
$engine = new WeEngine();函數
執行start()函數post
1:若是該公衆號在咱們平臺沒有對應的帳戶exit('Miss Account.');ui
2:根據微信平臺傳遞來的參數和平臺綁定的token進行校驗($this->account->checkSign()) 檢測失敗 exit('Check Sign Fail.');
3:檢測平臺的請求方式,若是成功 執行到這行說明帳戶綁定成功 則更新帳戶狀態 咱們能夠在後臺發現綁定成功幾個字
4:微信交互信息都用post形式推送XML數據到咱們服務器
判斷是否採用加密通訊 若是加密先解密,若是WeAccount來解析交互的XML信息
原始文本交互信息以下:
<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>1348831860</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[this is a test]]></Content>
<MsgId>1234567890123456</MsgId>
</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裏的<subscribes>下是否有配置過當前的事件
若是配置過事件則會去對應模塊下查詢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數據響應給騰訊服務器