<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>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                _Give it some time, everything will be okay. -- 《那些年我們瘋狂的青春/青春洋溢色彩/This Youth is Crazy》_ ## 4.3.1 模擬的業務場景 假設我們需要為“奔跑吧兄弟”綜藝節目開發一套手機App的投票接口,以供用戶在觀看電視的同時,可以進行投票活動參與互動。 下面將以此模擬的業務場景,提供一個接口開發實戰的過程。 ## 4.3.2 源代碼下載 [PhalApi-Demo-Vote](http://git.oschina.net/dogstar/PhalApi-Demo-Vote) ## 4.3.3 接口總列表 以下是我們根據業務需求整理出來的接口: + 1、用戶可以通過微信、QQ、新浪微博等渠道進行第三方登錄 + 2、用戶可以創建團隊進行參賽,但隊名不能重復 + 3、用戶可以對已參賽的團隊進行投票,且每個用戶每天投票最多不能超過3次,支持可配置 + 4、獲取已參賽團隊的得票排行榜 ## 4.3.4 主要涉及技術功能點 + 1、使用User擴展類庫實現第三方登錄操作 + 2、使用緩存存放用戶每天投票的次數(為方便起見,使用文件緩存,不落地) + 3、對接口進行簽名驗證(為方便起見,固定sign簽名) + 4、數據庫的基本操作 + 5、自動化腳本的使用 ## 4.3.4 快速開發流程 (題外音:整個示例的開發,我個人在單元測試驅動開發下,只用了兩個多小時,其中還包括對模板場景的業務構思、建表、編寫單元測試代碼等)。 ###(1)創建項目和部署環境 把PhalApi最新的框架代碼下載后,并將User擴展類庫按文檔說明配置后,將項目部署到了以下接口域名: ``` http://api.vote.phalapi.com ``` 測試一下: ```javascript http://api.vote.phalapi.com/vote/?sign=phalapi //返回 { "ret": 200, "data": { "title": "Hello World!", "content": "PHPer您好,歡迎使用PhalApi!", "version": "1.1.4", "time": 1431796924 }, "msg": "" } ``` Good! 下面是簡明的開發過程。 ###(2)單元測試驅動開發 在定好接口后: ```javascript <?php class Api_Act extends PhalApi_Api { public function joinIn() { } public function showList() { } public function vote() { } } ``` 便可使用腳本,快速生成單元測試的骨架代碼: ```javascript $ cd ./Vote/Tests/Api $ phalapi_buildtests ../../Api/Act.php Api_Act ../test_env.php > Api_Act_Test.php ``` ###(3)快速開發 開發過程此處略,但在單元測試驅動的引導下,很快就產出了以下高質量的代碼: ```javascript . ├── Api │?? ├── Act.php │?? └── Default.php ├── Common │?? └── SignFilter.php ├── Domain │?? ├── Team.php │?? └── Vote.php ├── Model │?? ├── Team.php │?? ├── UserVoteRecord.php │?? └── Vote.php └── Tests ├── Api │?? ├── Api_Act_Test.php │?? └── Api_Default_Test.php ├── Domain ├── Model ├── phpunit.xml └── test_env.php ``` ###(4)單元測試全部通過了! 為了方便大家查看,已省略了部分的調試內容,但保留了測試過程中全部執行的SQL語句,如下: ```javascript $ phpunit ./Api_Act_Test.php PHPUnit 4.3.4 by Sebastian Bergmann. [1 - 0.06911s]DELETE FROM phalapi_team WHERE (team_name = 'test team name');<br> [2 - 0.06487s]SELECT expires_time FROM phalapi_user_session_1 WHERE (user_id = '1') AND (token = '193CE82D1F4588A9A168BDE6E6B83868B1464F523D16C05206F308E51EB91731');<br> [3 - 0.06553s]SELECT COUNT(id) FROM phalapi_team WHERE (team_name = 'test team name');<br> [4 - 0.0653s]INSERT INTO phalapi_team (team_name) VALUES ('test team name');<br> [5 - 0.0699s]SELECT expires_time FROM phalapi_user_session_1 WHERE (user_id = '1') AND (token = '193CE82D1F4588A9A168BDE6E6B83868B1464F523D16C05206F308E51EB91731');<br> [6 - 0.06555s]SELECT COUNT(id) FROM phalapi_team WHERE (team_name = 'test team name');<br> [9 - 0.06778s]SELECT expires_time FROM phalapi_user_session_1 WHERE (user_id = '1') AND (token = '193CE82D1F4588A9A168BDE6E6B83868B1464F523D16C05206F308E51EB91731');<br> [10 - 0.06603s]SELECT COUNT(id) FROM phalapi_team WHERE (id = 3);<br> [11 - 0.06825s]SELECT vote_num FROM phalapi_vote WHERE (team_id = 3) LIMIT 1;<br> [12 - 0.07374s]UPDATE phalapi_vote SET team_id = 3, vote_num = 22 WHERE (team_id = 3);<br> [13 - 0.07012s]SELECT expires_time FROM phalapi_user_session_1 WHERE (user_id = '1') AND (token = '193CE82D1F4588A9A168BDE6E6B83868B1464F523D16C05206F308E51EB91731');<br> [14 - 0.06682s]SELECT COUNT(id) FROM phalapi_team WHERE (id = 3);<br> [15 - 0.07433s]SELECT vote_num FROM phalapi_vote WHERE (team_id = 3) LIMIT 1;<br> [16 - 0.07283s]UPDATE phalapi_vote SET team_id = 3, vote_num = 23 WHERE (team_id = 3);<br> [17 - 0.07307s]SELECT expires_time FROM phalapi_user_session_1 WHERE (user_id = '1') AND (token = '193CE82D1F4588A9A168BDE6E6B83868B1464F523D16C05206F308E51EB91731');<br> [18 - 0.07501s]SELECT COUNT(id) FROM phalapi_team WHERE (id = 3);<br> [19 - 0.07135s]SELECT vote_num FROM phalapi_vote WHERE (team_id = 3) LIMIT 1;<br> [20 - 0.07653s]UPDATE phalapi_vote SET team_id = 3, vote_num = 24 WHERE (team_id = 3);<br> [21 - 0.07215s]SELECT expires_time FROM phalapi_user_session_1 WHERE (user_id = '1') AND (token = '193CE82D1F4588A9A168BDE6E6B83868B1464F523D16C05206F308E51EB91731');<br> [22 - 0.06722s]SELECT COUNT(id) FROM phalapi_team WHERE (id = 3);<br> [23 - 0.06506s]SELECT expires_time FROM phalapi_user_session_1 WHERE (user_id = '1') AND (token = '193CE82D1F4588A9A168BDE6E6B83868B1464F523D16C05206F308E51EB91731');<br> [24 - 0.06732s]SELECT COUNT(id) FROM phalapi_team WHERE (id = 404);<br> Time: 1.97 seconds, Memory: 7.00Mb OK (4 tests, 42 assertions) ``` ###(5)運行效果 - Part 1 在我們通過第三方登錄后,我們就可以這樣進行接口操作了。 首先,讓我們添加兩個參賽團隊: ```javascript //奔跑吧兄弟(藍隊) http://api.vote.phalapi.com/vote/?sign=phalapi&service=Act.JoinIn&team_name=%E5%A5%94%E8%B7%91%E5%90%A7%E5%85%84%E5%BC%9F%EF%BC%88%E8%93%9D%E9%98%9F%EF%BC%89&token=193CE82D1F4588A9A168BDE6E6B83868B1464F523D16C05206F308E51EB91731&user_id=1 //返回 { "ret": 200, "data": { "code": 0, "team_id": "5" }, "msg": "" } //奔跑吧兄弟(紅隊) http://api.vote.phalapi.com/vote/?sign=phalapi&service=Act.JoinIn&team_name=%E5%A5%94%E8%B7%91%E5%90%A7%E5%85%84%E5%BC%9F%EF%BC%88%E7%BA%A2%E9%98%9F%EF%BC%89&token=193CE82D1F4588A9A168BDE6E6B83868B1464F523D16C05206F308E51EB91731&user_id=1 //返回 { "ret": 200, "data": { "code": 0, "team_id": "6" }, "msg": "" } ``` 然后,讓我們進行瘋狂地投票: ```javascript //第一次投票 http://api.vote.phalapi.com/vote/?sign=phalapi&service=Act.Vote&team_id=5&token=193CE82D1F4588A9A168BDE6E6B83868B1464F523D16C05206F308E51EB91731&user_id=1 //返回 {"ret":200,"data":{"code":0,"vote_num":1},"msg":""} //第二次投票 http://api.vote.phalapi.com/vote/?sign=phalapi&service=Act.Vote&team_id=5&token=193CE82D1F4588A9A168BDE6E6B83868B1464F523D16C05206F308E51EB91731&user_id=1 //返回 {"ret":200,"data":{"code":0,"vote_num":2},"msg":""} //第三次投票 http://api.vote.phalapi.com/vote/?sign=phalapi&service=Act.Vote&team_id=5&token=193CE82D1F4588A9A168BDE6E6B83868B1464F523D16C05206F308E51EB91731&user_id=1 //返回 {"ret":200,"data":{"code":0,"vote_num":3},"msg":""} //第四次投票 http://api.vote.phalapi.com/vote/?sign=phalapi&service=Act.Vote&team_id=5&token=193CE82D1F4588A9A168BDE6E6B83868B1464F523D16C05206F308E51EB91731&user_id=1 //返回 - 注意此返回! {"ret":200,"data":{"code":2,"vote_num":0},"msg":""} ``` 最后,看一下排行榜: ```javascript http://api.vote.phalapi.com/vote/?sign=phalapi&service=Act.ShowList&token=193CE82D1F4588A9A168BDE6E6B83868B1464F523D16C05206F308E51EB91731&user_id=1 //返回 { "ret": 200, "data": { "code": 0, "teams": [ { "id": 5, "team_name": "奔跑吧兄弟(藍隊)", "vote_num": 3 }, { "id": 6, "team_name": "奔跑吧兄弟(紅隊)", "vote_num": 0 } ] }, "msg": "" } ``` 至此,我們已經可以把接口交付給客戶端同學使用啦! 當然,我們還需要稍微整理輸出WIKI文檔~~~ 部分接口返回的結果可能與你實際看到的不一樣,因為數據會在變化而且有單元測試的測試數據。 ###(6)運行效果 - Part 2 接口服務,不僅僅需要提供正常的業務功能,還需要考慮到各種客戶端使用的情況,包括非法的請求,或者不合的調用,比如防刷票。 這一部分,主要展示接口在各種異常情況下的響應能力。 ####簽名失敗 ```javascript http://api.vote.phalapi.com/vote/?sign=XXX&service=Act.JoinIn&team_name=%E5%A5%94%E8%B7%91%E5%90%A7%E5%85%84%E5%BC%9F%EF%BC%88%E7%BA%A2%E9%98%9F%EF%BC%89&token=193CE82D1F4588A9A168BDE6E6B83868B1464F523D16C05206F308E51EB91731&user_id=1 //返回 { "ret": 400, "data": [ ], "msg": "非法請求:wrong sign" } ``` ####無登錄態 ```javascript http://api.vote.phalapi.com/vote/?sign=phalapi&service=Act.JoinIn&team_name=%E5%A5%94%E8%B7%91%E5%90%A7%E5%85%84%E5%BC%9F%EF%BC%88%E7%BA%A2%E9%98%9F%EF%BC%89&token=XXX&user_id=1 //返回 { "ret": 401, "data": [ ], "msg": "非法請求:user need to login again" } ``` ####重復參賽 ```javascript http://api.vote.phalapi.com/vote/?sign=phalapi&service=Act.JoinIn&team_name=%E5%A5%94%E8%B7%91%E5%90%A7%E5%85%84%E5%BC%9F%EF%BC%88%E7%BA%A2%E9%98%9F%EF%BC%89&token=193CE82D1F4588A9A168BDE6E6B83868B1464F523D16C05206F308E51EB91731&user_id=1 //返回 { "ret": 200, "data": { "code": 1, "team_id": 0 }, "msg": "" } ``` ####當天投票次數已達最大 ```javascript //第四次投票后 http://api.vote.phalapi.com/vote/?sign=phalapi&service=Act.Vote&team_id=5&token=193CE82D1F4588A9A168BDE6E6B83868B1464F523D16C05206F308E51EB91731&user_id=1 //返回 - 注意此返回! { "ret": 200, "data": { "code": 2, "vote_num": 0 }, "msg": "" } ``` ####投票的團隊不存在 ```javascript http://api.vote.phalapi.com/vote/?sign=phalapi&service=Act.Vote&team_id=404&token=193CE82D1F4588A9A168BDE6E6B83868B1464F523D16C05206F308E51EB91731&user_id=1 //返回 { "ret": 200, "data": { "code": 1, "vote_num": 0 }, "msg": "" } ``` 在進行上面的非法請求后,我們可以同時關注后臺的日志: ```javascript $ tailf ./Runtime/log/201505/20150517.log 2015-05-17 01:35:32|DEBUG|user not login|{"userId":null,"token":null} 2015-05-17 01:36:01|DEBUG|user can not vote today|{"userId":1,"teamId":5} 2015-05-17 01:37:52|DEBUG|user can not vote today|{"userId":1,"teamId":5} 2015-05-17 01:45:25|DEBUG|user need to login again|{"expiresTime":0,"userId":"1","token":"XXX"} 2015-05-17 01:48:13|DEBUG|user can not vote today|{"userId":1,"teamId":5} ``` ###(7)需要的數據庫表 以下為關鍵的表,其他表,可以通過腳本自動生成,然后導入。 ```javascript -- ---------------------------- -- Table structure for `phalapi_team` -- ---------------------------- DROP TABLE IF EXISTS `phalapi_team`; CREATE TABLE `phalapi_team` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `team_name` varchar(100) DEFAULT '' COMMENT '隊名', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of phalapi_team -- ---------------------------- INSERT INTO `phalapi_team` VALUES ('3', 'egg team'); INSERT INTO `phalapi_team` VALUES ('5', '奔跑吧兄弟(藍隊)'); INSERT INTO `phalapi_team` VALUES ('6', '奔跑吧兄弟(紅隊)'); INSERT INTO `phalapi_team` VALUES ('17', 'test team name'); INSERT INTO `phalapi_user` VALUES ('1', 'wx_edebc877070133c65161d00799e00544', 'weixinName', '******', '4CHqOhe1Jxi3X9HmRfPOXygDnU267eCA', '1431790647', 'phpunit.png'); INSERT INTO `phalapi_user_login_weixin` VALUES ('1', 'wx_122348561111', 'ASDF', '130000000', '1'); INSERT INTO `phalapi_user_session_1` VALUES ('1', '1', '193CE82D1F4588A9A168BDE6E6B83868B1464F523D16C05206F308E51EB91731', '', '1', '1431790647', '1934382647', null); ``` ## 4.3.4 腳本的使用 ###(1)創建項目腳本 - phalapi_buildapp 此腳本可用于快速創建項目,其使用如下: ```javascript $ ./PhalApi/phalapi-buildapp Usage: ./PhalApi/phalapi-buildapp <app> ``` 此腳本會根據Demo示例,快速生成一個新的項目。 ###(2)自動生成單元測試骨架腳本 - phalapi_buildtest 這是一個用來自動生成單元測試骨架的腳本,其使用如下: ```javascript $ phalapi-buildtest Usage: php /usr/bin/phalapi-buildtest <file_path> <class_name> [bootstrap] [author = dogstar] Demo: php ./build_phpunit_test_tpl.php ./Demo.php Demo > Demo_Test.php ``` 然后,我們就可以使用輔助的PhalApiTestRunner::go()進行單元測試: ```javascript public function testShowList() { //Step 1. 構建請求URL $url = 'service=Act.ShowList&sign=phalapi&user_id=1&token=193CE82D1F4588A9A168BDE6E6B83868B1464F523D16C05206F308E51EB91731'; //Step 2. 執行請求 $rs = PhalApiTestRunner::go($url); //var_dump($rs); //Step 3. 驗證 $this->assertNotEmpty($rs); $this->assertArrayHasKey('code', $rs); $this->assertArrayHasKey('teams', $rs); $this->assertEquals(0, $rs['code']); $this->assertNotEmpty($rs['teams']); foreach ($rs['teams'] as $team) { $this->assertArrayHasKey('id', $team); $this->assertArrayHasKey('team_name', $team); $this->assertArrayHasKey('vote_num', $team); $this->assertGreaterThanOrEqual(0, $team['vote_num']); } } ``` ###(3)自動生成分表建表SQL語句 - phalapi_buildsqls 此腳本用于根據dbs.php配置和./Data/*.sql文件生成完整的建表語句,其使用如下: ```javascript $ ./PhalApi/phalapi-buildsqls Usage: ./PhalApi/phalapi-buildsqls <dbs.php> <table> [engine=InnoDB] ``` 假設我們需要對vote進行分表,拆分成3個表,可以這樣配置: ```javascript //$ vim ./Config/dbs.php 'vote' => array( 'prefix' => 'phalapi_', 'key' => 'id', 'map' => array( array('start' => 0, 'end' => 2, 'db' => 'db_vote'), ), ), ``` 然后準備基本的建表語句: ```javascript //$vim ./Data/vote.sql `team_id` bigint(20) DEFAULT '0', `vote_num` int(11) DEFAULT '0', ``` 最后,執行生成腳本: ```javascript $ phalapi-buildsqls ./Config/dbs.php vote /** * DB: phalapi_vote */ CREATE TABLE `phalapi_vote_0` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `team_id` bigint(20) DEFAULT '0', `vote_num` int(11) DEFAULT '0', `ext_data` text COMMENT 'json data here', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `phalapi_vote_1` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `team_id` bigint(20) DEFAULT '0', `vote_num` int(11) DEFAULT '0', `ext_data` text COMMENT 'json data here', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `phalapi_vote_2` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `team_id` bigint(20) DEFAULT '0', `vote_num` int(11) DEFAULT '0', `ext_data` text COMMENT 'json data here', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; ``` ## 4.3.5 在線接口參數查看 可以通過以下鏈接,在線實時查看接口參數: ```javascript //參賽接口 http://api.vote.phalapi.com/vote/checkApiParams.php?service=Act.JoinIn //投票接口 http://api.vote.phalapi.com/vote/checkApiParams.php?service=Act.Vote //排行榜接口 http://api.vote.phalapi.com/vote/checkApiParams.php?service=Act.ShowList ``` 其中,投票接口的參數如下: ![a pic](http://webtools.qiniudn.com/20150517.jpg)
                  <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>

                              哎呀哎呀视频在线观看