在較早的一篇文章中,實現了一個公用平台PHP類,見http://blog.csdn.net/c80486/article/details/12316305
使用這個類以後,公用平台程式變成以下這樣簡單的一個形式:
主程式只有三行:
include_once 'jostudio.wechat.php';
$object = new WeChat(TOKEN, "onMessage"); ////建立一個WeChat類的執行個體
$object->process(); //處理訊息
再寫一個訊息處理函數
function onMessage(WeChat $object, $messageType, $content, $arg1, $arg2) {
switch(messageType) {
... ...
}
}
這種程式結構很像用C語言進行windows編程( 一個WinMain主程式,一個訊息處理函數)
然而,隨著處理邏輯的增加,訊息處理函數的代碼會變得很複雜(可能有很多個switch),把所有功能寫在一個函數中是不好的風格(好的編程風格是一個函數最好不要超過一屏)。
一個公用平台往往提供多個應用功能,比如:
"歡迎您!回複數字選擇項目:\r\n1 講笑話 2 聽音樂"
上述例子有兩個應用,1是講笑話,2是聽音樂。 當然 主菜單選擇本身也可以看作是一個應用
我們的程式要記錄使用者上一次輸入時的狀態, 比如:記錄用戶當前是在什麼應用狀態,是在主菜單呢、還是在笑話應用、音樂應用。
否則,每次使用者輸入時,不知道是對哪個應用進行輸入。
由於公用平台並不提供類似cookie這樣的功能,我們必須在自己的網站上記錄使用者的狀態。
為些,我首先寫了一個User類,用於儲存用戶狀態。(源碼檔案: jostudio.user.php, 下載地址: http://download.csdn.net/detail/c80486/6361281)
一個用戶的數據以文字檔形式儲存在一個檔案中,檔案名稱是用戶OpenID號,統一放在user目錄下。數據格式採用JSON。
初始狀態時,用戶有二個狀態變量:App 和 Stage, 兩個變數均為string型
App 用於記錄用戶當前在哪個應用
Stage 用於記錄用戶在該應用中完成了哪一步
User類的使用方法:
1, 創建用戶: $user = new User($openId, $savePath) ; //savePath是存盤目錄
2, 寫入狀態: $user->setAppState($app, $stage);
寫入狀態值後將自動存盤
3, 讀出App狀態值: $user->getApp();
4, 讀出Stage狀態值: $user->getStage();
5,設定使用者自訂的鍵值(形如:$key=$value) $user->set($key, $value);
6,讀出使用者自訂的鍵值 $user->get($key);
重新設計這個例子:
"歡迎您!回複數字選擇項目:\r\n1 講笑話 2 聽音樂"
分成三個應用狀態:
App = "main" 主菜單選擇
App = "joke" 講笑話
App = "music" 聽音樂
修改訊息處理函數如下:
function onMessage(WeChat $object, $messageType, $content, $arg1, $arg2) {
$user = new User($object->fromUser, $savePath) ; //$object->fromUser就是使用者的OpenID
switch($user->getApp()) {
case "":
case "main":
mainMessage($object, $messageType, $content, $arg1, $arg2);
break;
case "joke":
jokeMessage($object, $messageType, $content, $arg1, $arg2);
break;
case "music":
musicMessage($object, $messageType, $content, $arg1, $arg2);
break;
}
}
mainMessage()函數負責主菜單的訊息處理, jokeMessage()函數負責笑話應用的訊息處理, musicMessage()函數負責音樂應用的訊息處理, ...
通過這樣修改,通過判斷不同的app狀態,把訊息處理分散到三個函數mainMessage, jokeMessage, musicMessage中,程式優雅很多了。
我把三個訊息處理函數分別寫在三個檔案中,每個檔案唯寫一個函數, 再在主程式中include進來
app.main.php檔案包含mainMessage()
app.joke.php檔案包含jokeMessage()
app.music.php檔案包含jokeMessage()
這什麼要這樣拆分一個程式呢?
這是模組切分的道理,好處是,整體程式合理切分,每一個檔案、函數的功能都很清晰簡單,耦合程度不高;
每一個函數代碼不會很長,容易看懂,不容易出錯,也可分工由不同的人編碼
在實際應用中,我把 switch($user->getApp()) { ... } 這一段也省了
利用PHP的call_user_func()函數,通過判斷App名稱,動態調用相應的訊息處理函數
具體不再詳述,見代碼吧 (:http://download.csdn.net/detail/c80486/6361281)
代碼在/易信平台上測試通過.