<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                ? ? ? ?CleverCode前一段時間想去接觸一下微信開發,申請了一個人訂閱號,發現暫不能申請個人認證,而且沒有微信接口的很多權限,也沒有自定義菜單的權限(開發模式下)。在開發模式下,只能到手公眾號里面的回復信息,然后響應。 ## 1 項目背景 ? ? ? ? ? CleverCode想了很久,運營一個什么樣的公眾號,比較好呢?現在的公眾號太多了。比較好的點子,基本都被人想到了。那幾天CleverCode的遇到點煩心事,心情不大爽,就想著能不能設計一個講笑話的公眾號,大家能夠在里面講笑話,然后查看笑話,開心一下自己。講笑話后能夠獲取金幣。積累到一定的金幣后,可以兌換獎品。獎品的方式可以是充話費的形式。 ? ? ? ? ? 說干就干。腦袋一熱,CleverCode就開始瘋狂的忙碌起來的了............................ ?? ## 2 需求分析 ? ? ? ? CleverCode發現個人訂閱號,只能簡單收到客戶的信息,然后響應信息。然后CleverCode就想,不如就讓用戶輸入0-9的數字,組合成命令,這樣服務器每次收到不同的數字后,去響應不同的請求就可以了。(這種方式基本停留在沒有圖片,顏色;只有文字交互的時代...........誰叫咋申請的訂閱號,沒有認證,就沒有一些接口的權限)。 ## 3 源碼下載 ? ? ? ?[http://download.csdn.net/detail/clevercode/8916699](http://download.csdn.net/detail/clevercode/8916699)。 ## 4 項目演示 ? ? ? ?如果你想查看本微信的詳細的演示效果,可以在微信中搜索微信號:taihaoxiaole888。或者掃描下方二維碼關注。 ![](https://box.kancloud.cn/2016-04-07_5705f500466c8.jpg) ? ? ?![](https://box.kancloud.cn/2016-04-07_5705f5005d20c.jpg) ![](https://box.kancloud.cn/2016-04-07_5705f50077f5e.jpg) ## 5 ?設計過程 ### 5.1 微信配置接口 ? ? ? ?申請完微信訂閱號后,要想微信開發,必須在微信后臺([mp.weixin.qq.com](https://mp.weixin.qq.com/))切換到開發模式,然后配置接口。如下圖。http://xxxx.com是我服務器的域名地址。如果沒有服務器也可以用新浪的sae。/apithxl/interface表示的我是使用的zend framework框架。這個url可以是任意的,只要能夠訪問得到即可。例如http://xxxx.com/api.php,http://xxxx.com/api.jsp等等。 ![](https://box.kancloud.cn/2016-04-07_5705f50096c5f.jpg) ### 5.2 微信接口交互過程 ? ? ? ? 當用戶回復內容后,微信需要將用戶回復的先傳到自己的服務,如果配置成為了開發模式,微信會將調用接口(http://xxxxx.com/apithxl/interface),通過post方式將回復的內容發送到接口服務器上,我接口服務器處理完請求后,只需要輸出一個xml信息,微信服務器獲取這個xml信息后,在將獲取的信息返回給微信用戶。具體過程如下圖。 ![](https://box.kancloud.cn/2016-04-07_5705f500c24b9.jpg) ### 5.3 檢查簽名 ? ? ? ? 當用戶配置完接口后,需要提交配置,微信向接口發送get請求的字符串。你需要echo它的字符串。這個在微信開發者文檔中都會有,我代碼中WeiXinCheck::checkSignature($signature, $timestamp, $nonce)也有。 ## 6 接口設計架構 ### 6.1 接口工作原理 ? ? ? ? ? ?當接口收到微信服務器發送過來的請求后,首先需要到命令解析中心,分析出得到是什么請求。然后將得到命令發送到命令調用中心;調度中心會根據不同的命令調用不用執行邏輯,然后返回結果。 ![](https://box.kancloud.cn/2016-04-07_5705f500e2c53.jpg) ApithxlController.php,主函數執行過程如下。入口函數為interfaceAction(),這個是zend framework框架的寫法。首先通過_getRequest($request)方法保存參數,然后驗證簽名?,通過CmdCenter::findCmd($request)解析命令,通過switch ($cmd)調用命令,通過$this->displayUTF8($retArray, 'thxl/validate.html')返回xml格式的內容。 ~~~ <?php /** * ApithxlController.php * * 太好笑了接口 * * Copyright (c) 2015 http://blog.csdn.net/CleverCode * * modification history: * -------------------- * 2015/7/10, by CleverCode, Create * */ define("TOKEN", "CleverCode"); define("HTTP_RAW_POST_DATA_TEST", WEB_ROOT_DIR . '/log/http_raw_post_data_test.txt'); define("HTTP_REQUEST_RESPONSE_LOG", WEB_ROOT_DIR . '/log/http_request_response_log-' . date('Y-m-d') . '.txt'); class ApithxlController extends My_Controller{ public $check_auth = false; public $check_auth_menu = false; /** * 命令接口 * * @return void */ function interfaceAction(){ $ret = $this->_interface(); } /** * 私有命令接口 * * @return string 成功返回'OK',失敗返回錯誤信息 */ private function _interface(){ $request = array(); // 獲取參數 $ret = $this->_getRequest($request); if ($ret != 'OK') { return $ret; } // 檢查簽名 if (!WeiXinCheck::checkSignature($request["signature"], $request["timestamp"], $request["nonce"])) { return 'checkSignature retrun false!'; } // 請求日志 if (!empty($GLOBALS["HTTP_RAW_POST_DATA"])) { logMsg(HTTP_REQUEST_RESPONSE_LOG, 'REQUEST', $GLOBALS["HTTP_RAW_POST_DATA"]); } // 解析文本命令 $cmd = CmdCenter::findCmd($request); $retArray = array(); $retArray['request'] = $request; // 執行命令 switch ($cmd) { // 校驗 case 'validate' : $retMessage = InfoCenter::validate($request, &$retArray); if ($retMessage != 'OK') { return; } $this->displayUTF8($retArray, 'thxl/validate.html'); break; // 再來一個 case 'getOneAgain' : $retMessage = InfoCenter::getOneAgain($request, &$retArray); if ($retMessage != 'OK') { return; } $this->displayUTF8($retArray, 'thxl/textMsg.html'); break; // 查看幫助 case 'readHelp' : $retMessage = InfoCenter::readHelp($request, &$retArray); if ($retMessage != 'OK') { return; } $this->displayUTF8($retArray, 'thxl/textMsg.html'); break; // 賬戶詳情 case 'accountDetail' : $retMessage = InfoCenter::accountDetail($request, &$retArray); if ($retMessage != 'OK') { return; } $this->displayUTF8($retArray, 'thxl/textMsg.html'); break; // 兌換獎品 case 'exchangePrizesDescribe' : $retMessage = InfoCenter::exchangePrizesDescribe($request, &$retArray); if ($retMessage != 'OK') { return; } $this->displayUTF8($retArray, 'thxl/textMsg.html'); break; // 掙取金幣 case 'earnCoin' : $retMessage = InfoCenter::earnCoin($request, &$retArray); if ($retMessage != 'OK') { return; } $this->displayUTF8($retArray, 'thxl/textMsg.html'); break; // 點贊 case 'dianZan' : $retMessage = InfoCenter::dianZan($request, &$retArray); if ($retMessage != 'OK') { return; } $this->displayUTF8($retArray, 'thxl/textMsg.html'); break; // 我講一個 case 'addJoke' : $retMessage = InfoCenter::addJoke($request, &$retArray); if ($retMessage != 'OK') { return; } $this->displayUTF8($retArray, 'thxl/textMsg.html'); break; // 我的笑話 case 'myJoke' : $retMessage = InfoCenter::myJoke($request, &$retArray); if ($retMessage != 'OK') { return; } $this->displayUTF8($retArray, 'thxl/textMsg.html'); break; // 金幣記錄 case 'tradeLog' : $retMessage = InfoCenter::tradeLog($request, &$retArray); if ($retMessage != 'OK') { return; } $this->displayUTF8($retArray, 'thxl/textMsg.html'); break; // 兌換獎品 case 'exchangePrizes' : $retMessage = InfoCenter::exchangePrizes($request, &$retArray); if ($retMessage != 'OK') { return; } $this->displayUTF8($retArray, 'thxl/textMsg.html'); break; // 給客服留言 case 'giveMessage' : $retMessage = InfoCenter::giveMessage($request, &$retArray); if ($retMessage != 'OK') { return; } $this->displayUTF8($retArray, 'thxl/textMsg.html'); break; // 關注 case 'subscribe' : $retMessage = InfoCenter::subscribe($request, &$retArray); if ($retMessage != 'OK') { return; } $this->displayUTF8($retArray, 'thxl/textMsg.html'); break; // 默認 default : $retMessage = InfoCenter::cmdNotFound($request, &$retArray); if ($retMessage != 'OK') { return; } $this->displayUTF8($retArray, 'thxl/textMsg.html'); break; } } /** * 獲取請求參數 * * @param array $request 請求數組 * @return string 成功返回'OK',失敗返回錯誤信息 */ private function _getRequest(&$request){ // 本機平臺 if (SYS_RELEASE == 0) { $_GET["signature"] = '5b7b4a7c06b3bc4116a2fcbbbb2c887557cd07a6'; $_GET["timestamp"] = '1436056391'; $_GET["nonce"] = '1929760760'; // $_GET["echostr"] = 'this is from echostr'; $fp = fopen(HTTP_RAW_POST_DATA_TEST, "r"); $GLOBALS["HTTP_RAW_POST_DATA"] = fread($fp, filesize(HTTP_RAW_POST_DATA_TEST)); fclose($fp); } $request['signature'] = $_GET["signature"]; $request['timestamp'] = $_GET["timestamp"]; $request['nonce'] = $_GET["nonce"]; $request['echostr'] = $_GET["echostr"]; if (isset($GLOBALS["HTTP_RAW_POST_DATA"]) && !empty($GLOBALS["HTTP_RAW_POST_DATA"])) { $request['post'] = array(); $request['post']['items'] = XmlCenter::xmlToArray($GLOBALS["HTTP_RAW_POST_DATA"]); if (isset($request['post']['items']['Content'])) { $request['post']['items']['Content'] = iconv('UTF-8', 'GBK', $request['post']['items']['Content']); } $request['post']['string'] = $GLOBALS["HTTP_RAW_POST_DATA"]; // 插入請求日志 UserLog::insertRequestLog($request); } return 'OK'; } } ~~~ ### 6.2 保存get與post傳輸xml數據 ? ? ? ? ?每次微信服務器請求都會傳輸get參數,與post的xml數據。需要將這些數據保存到$request數組中。xml數據的格式如下。 ~~~ <xml><ToUserName><![CDATA[gh_5bcc295a14c4]]></ToUserName> <FromUserName><![CDATA[oihwct-iYa_xYXHAR2ZmnAPasEzQ]]></FromUserName> <CreateTime>1436275541</CreateTime> <MsgType><![CDATA[text]]></MsgType> <Content><![CDATA[9#123456789]]></Content> <MsgId>6168756476849070426</MsgId> </xml> ~~~ 在ApithxlController.php,通過_getRequest(&$request)函數,將get與post參數保存到$request數組中。 ### 6.2 命令解析中心 ? ? ? ? 當保存完參數后,需要對用戶輸入的內容進行解析,分析的數字命令是什么。在CmdCenter.php,查找的命令的入口函數式findCmd($request);首先查找是否是接口驗證的命令,然后在從文本中查找命令,最后查找是否為事件命令。 ~~~ <?php /** * CmdCenter.php * * 查找cmd * * Copyright (c) 2015 http://blog.csdn.net/CleverCode * * modification history: * -------------------- * 2015/7/10, by CleverCode, Create * */ class CmdCenter{ // 命名字典 public static $cmdMap = array( 'validate' => '接口驗證', 'subscribe' => '關注', 'readHelp' => '查看幫助', 'getOneAgain' => '發布一個', 'accountDetail' => '賬戶詳情', 'earnCoin' => '掙取金幣', 'dianZan' => '點贊', 'exchangePrizesDescribe' => '兌換獎品描述', 'addJoke' => '我講一個', 'myJoke' => '我的笑話', 'tradeLog' => '交易記錄', 'exchangePrizes' => '兌換獎品', 'giveMessage' => '給客服留言' ); // 數字到字符串命令字典 public static $numToCmdStr = array( '0' => 'readHelp', '1' => 'getOneAgain', '2' => 'exchangePrizesDescribe', '3' => 'earnCoin', '4' => 'accountDetail', '5' => 'myJoke', '6' => 'tradeLog', '7' => 'addJoke', '8' => 'dianZan', '9' => 'giveMessage', '100' => 'exchangePrizes' ); /** * 查找命令 * * @param array $request 請求數組 * @return string cmd */ public static function findCmd($request){ // 驗證cmd $cmd = self::findValidateCmd($request); if (strlen($cmd) > 0) { return self::checkCmdValid($cmd); } // 查找文本命令 $cmd = self::findTextCmd($request); if (strlen($cmd) > 0) { return self::checkCmdValid($cmd); } // 查找事件命令 $cmd = self::findEventCmd($request); if (strlen($cmd) > 0) { return self::checkCmdValid($cmd); } } /** * 檢查命令的有效性 * * @param string $cmd 命令 * @return string 有效返回$cmd,否則為空 */ public static function checkCmdValid($cmd){ if (isset(self::$cmdMap[$cmd])) { return $cmd; } } /** * 驗證命令 * * @param array $request 請求數組 * @return string cmd */ public static function findValidateCmd($request){ if (isset($request['echostr']) && strlen($request['echostr']) > 0) { return 'validate'; } } /** * 查找文本命令 * * @param array $request 請求數組 * @return string cmd */ public static function findTextCmd($request){ if (empty($request['post'])) { return; } $msgType = $request['post']['items']['MsgType']; if ($msgType != 'text') { return; } $content = $request['post']['items']['Content']; $cmd = trim($content); $cmd = ltrim($cmd, '【'); $cmd = rtrim($cmd, '】'); if (strpos($cmd, "#") !== false) { $cmd = substr($cmd, 0, strpos($cmd, "#")); } // 大寫 $cmd = strtoupper($cmd); if (!is_numeric($cmd)) { return; } if (isset(self::$numToCmdStr[$cmd])) { return self::$numToCmdStr[$cmd]; } } /** * 查找事件命令 * * @param array $request 請求數組 * @return string cmd */ public static function findEventCmd($request){ if (empty($request['post'])) { return; } $msgType = $request['post']['items']['MsgType']; if ($msgType != 'event') { return; } return $request['post']['items']['Event']; } } ~~~ ### 6.3 命令調度中心 ? ? ? ? ? 當分析出命令后,通過switch ($cmd){}進行調度,通過不同的cmd調用不同InfoCenter執行邏輯去執行。例如用戶回復的數字是1,那么命令解析中心就會把命令翻譯為getOneAgain,調度中心會給根據getOneAgain,調用InfoCenter::getOneAgain($request, &$retArray),最后通過displayUTF8($retArray, 'thxl/validate.html')輸出結果。 ### 6.4 命令執行中心 ? ? ? ? 當調度中心執行命令中心的函數后,函數根據自己的業務邏輯去執行,這里重點介紹的是回復的內容,我們可以使用smarty模板。然后將模板的內容讀入到字符串中。如下只舉例獲取幫助的代碼。 readHelpContent.html模板如下。 ~~~ 命令幫助: ******************** 0.回復0,查看幫助! 1.回復1,再來一個! 2.回復2,兌換獎品! 3.回復3,掙取金幣! 4.回復4,賬戶詳情! 5.回復5,我的笑話! 6.回復6,金幣記錄! 7.回復7#笑話標題#笑 話正文,我講一個! 8.回復8#笑話編號,點贊 ! 9.回復9#留言內容,給客 服留言! ******************** ~~~ 執行函數如下: ~~~ <?php /** * InfoCenter.php * * 信息中心 * * Copyright (c) 2015 http://blog.csdn.net/CleverCode * * modification history: * -------------------- * 2015/7/10, by CleverCode, Create * */ class InfoCenter{ //...... /** * 查看幫助 * * @param array $request 請求數組 * @param array $retArray 返回數組(輸出參數) * @return string 成功返回'OK',失敗返回錯誤信息 */ public static function readHelp($request, &$retArray){ $postStr = $request['post']['string']; if (empty($postStr)) { return 'empty($postStr)'; } $retArray['data']['fromUsername'] = $request['post']['items']['ToUserName']; $retArray['data']['toUsername'] = $request['post']['items']['FromUserName']; $retArray['data']['createTime'] = time(); $retArray['data']['msgType'] = 'text'; $content = SmartyWork::fetch(array(), 'thxl/readHelpContent.html'); $content = str_replace("\r", '', $content); $retArray['data']['content'] = $content; return 'OK'; } //...... } ~~~ ## 7 命令回復預覽 ### 7.1 關注事件 ? ? 關注公眾號后,會自動獲取1000金幣,然后默認將一個笑話。 ?? ![](https://box.kancloud.cn/2016-04-07_5705f5005d20c.jpg) ### 7.2 回復1 ? ? 回復1,可以隨機一個笑話。 ![](https://box.kancloud.cn/2016-04-07_5705f501143b2.jpg) ??? ### 7.2 回復2 ? ? 回復2,可以查看兌換獎品幫助。 ![](https://box.kancloud.cn/2016-04-07_5705f50163a93.jpg) ### 7.3 回復3 ? ? 回復3,掙取金幣。 ![](https://box.kancloud.cn/2016-04-07_5705f50185675.jpg) ### 7.4 回復4 ? ? 回復4,賬戶詳情! ![](https://box.kancloud.cn/2016-04-07_5705f501a4491.jpg) ### 7.5 回復5 回復5,我的笑話! ![](https://box.kancloud.cn/2016-04-07_5705f501c1647.jpg) ### 7.6 回復6 回復6,金幣記錄! ![](https://box.kancloud.cn/2016-04-07_5705f501e6c54.jpg) ### 7.7 回復7 回復7#笑話標題#笑 ? ?話正文,我講一個! ![](https://box.kancloud.cn/2016-04-07_5705f50210466.jpg) ### 7.8 回復8 回復8#笑話編號,點贊 ? ?! ![](https://box.kancloud.cn/2016-04-07_5705f5022fc2f.jpg) ### 7.9 回復9 回復9#留言內容,給客 ? ?服留言! ![](https://box.kancloud.cn/2016-04-07_5705f50248d87.jpg) ### 7.10 回復0 回復0,查看幫助。 ![](https://box.kancloud.cn/2016-04-07_5705f5026c5c4.jpg) ## 8 總結 ? ? ? ? ? 項目經過幾天的設計后,終于做完了,于是讓自己的好朋友測測,玩一玩。他們給出的點評是,還需要回復啊,不給個按鈕更好。我說沒權限獲取自定義按鈕。那個說笑話需要手動輸入那么多笑話的漢字,手機打字太費勁了。 ? ? ? ? ?種種的原因后,這個微信項目擱淺了,我現在想不出來更好的運營方法。后來一想還不如把我的經歷寫出來分享給大家。一個是相互學習與交流。也希望大家不要走學我,頭腦一發熱說干就干。一定需要很周密的計劃才行!謀定而后動..........................
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看