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

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                后臺接口絕大數情況下,都需要與數據庫進行交互,以獲取業務數據或者接收保存客戶端上報的數據。為方便后臺開發同學進行調試,以及實時查看全部執行的SQL語句,這里簡單地對全部執行的SQL語句進行調試模式下輸出。 ##2.13.1 開啟SQL調試 開啟調試模式很簡單,但這里和通常的框架不一樣,我們不是全部統一地開啟調試模式,因為在接口正常調用情況下返回非法的JSON會導致接口結果解析失敗。故我們通過添加調試參數來控制是否開啟SQL調試。如下: ```javascript //$vim ./Public/init.php //數據操作 - 基于NotORM DI()->notorm = function() { $debug = isset($_GET['debug']) ? true : false; return new PhalApi_DB_NotORM(DI()->config->get('dbs'), $debug); }; ``` > 特別注意: > 通常,我們的調試參數不應都簡單地使用&debug=1,而是各自定義,如 **復雜一點:&__phalapi_debug__=1** ,或者再添加一個簡單的驗簽,額外帶個參數校驗,如:&__phalapi__sign__=202cb962ac59075b964b07152d234b70。減少暴露SQL的風險。 ##2.13.2 調試示例 回到前面獲取用戶基本信息接口 /demo/?service=User.GetBaseInfo 的示例。 ###(1)正常情況下 請求: ```javascript http://dev.phalapi.com/demo/?service=User.GetBaseInfo&user_id=1 ``` 返回: ```javascript {"ret":200,"data":{"code":0,"msg":"","info":{"id":"1","name":"dogstar","note":"oschina"}},"msg":""} ``` ###(2)帶&debug=1調試下 請求: ``` http://dev.phalapi.com/demo/?service=User.GetBaseInfo&user_id=1&debug=1 ``` 返回: ```javascript [1 - 0.00057s]SELECT * FROM tbl_user WHERE (id = ?); -- 1 {"ret":200,"data":{"code":0,"msg":"","info":{"id":"1","name":"dogstar","note":"oschina"}},"msg":""} ``` ##2.13.3 一個錯誤的接口開發 有時,在進行接口開發時,會需要進行批量獲取的功能,如列表。但很多開發的同學可能會因為時間趕或者沒有意識去對SQL查詢進行優化,或者甚至不知道自己的接口背后隱藏著多少問題。下面是一個錯誤的開發示例。 ###(1)新增的批量獲取接口 假設我們在開發一個國際的項目,并且運行良好,BOSS說因業務需要,要加多一個接口以支持批量獲取用戶的基本信息,提供給國外某知名的社交平臺調用。 于是乎,我們很快就根據原來的單個獲取接口實現了新的接口: ```javascript //$vim ./Demo/Api/User.php <?php class Api_User extends PhalApi_Api { public function getRules() { return array( //... 'getMultiBaseInfo' => array( 'user_ids' => array('name' => 'user_ids', 'type' => 'array', 'format' => 'explode', 'require' => true), ), ); } //... public function getMultiBaseInfo() { $rs = array('code' => 0, 'msg' => '', 'list' => array()); $domain = new Domain_User(); foreach ($this->user_ids as $userId) { $rs['list'][] = $domain->getBaseInfo($userId); } return $rs; } } ``` ###(2)運行調用一下 顯然,我們可以很清楚地調用新增的接口: ``` http://dev.phalapi.com/demo/?service=User.GetMultiBaseInfo&user_ids=1,2,3 ``` 可返回: ```javascript { "ret": 200, "data": { "code": 0, "msg": "", "list": [ { "id": "1", "name": "dogstar", "note": "oschina" }, { "id": "2", "name": "Tom", "note": "USA" }, { "id": "3", "name": "King", "note": "game" } ] }, "msg": "" } ``` 假設我們已經有了這樣的數據庫表數據: ```javascript INSERT INTO `tbl_user` VALUES ('1', 'dogstar', 'oschina'); INSERT INTO `tbl_user` VALUES ('2', 'Tom', 'USA'); INSERT INTO `tbl_user` VALUES ('3', 'King', 'game'); ``` ###(3)這樣的問題? 這樣的問題,在對外黑盒調用的客戶端同學是發現不了的,對于測試人員來說也是無法感知的。但所犯的錯誤也是顯然易見的,就是沒有進行SQL的批量查詢優化,造成了很多不必要的重復查詢。 這里,根據后臺接口開發人員提供的調試參數(假設為:&debug=1),則我們可以快速發現存在的問題: ``` http://dev.phalapi.com/demo/?service=User.GetMultiBaseInfo&user_ids=1,2,3&debug=1 ``` 如下返回,我們看到了很多重復類似的查詢語句。 ```javascript [1 - 0.0005s]SELECT * FROM tbl_user WHERE (id = ?); -- 1 [2 - 0.00042s]SELECT * FROM tbl_user WHERE (id = ?); -- 2 [3 - 0.00038s]SELECT * FROM tbl_user WHERE (id = ?); -- 3 {"ret":200,"data":{"code":0,"msg":"","list":[{"id":"1","name":"dogstar","note":"oschina"},{"id":"2","name":"Tom","note":"USA"},{"id":"3","name":"King","note":"game"}]},"msg":""} ``` 上面輸出的調試信息,簡單補充一個格式: ```javascript [序號 - 所耗時間]SQl語句 -- [參數1, 參數2] ``` ###(4)如何改進? 這是一個很基本的問題,當然在實際項目中不會普通存在,這里只是作為一個示例加以說明。但讓人失望的是,實際項目確實存在為數不少的這樣的情況。可能是新人的技術和意識問題,也有可能是老同學的態度問題。所以,優化這么一個接口的批量SQL查詢不難,難的是如何才能讓新、老同學都注重這塊的SQL查詢優化呢?而不是等到線上服務器異常崩潰后再來推托責任。 具體的代碼改進,留給讀者自己實踐了。畢竟,看了,實踐了,才會真正深刻地掌握。 ##2.13.4 由此引申 + 這里不專門講述SQL的優化,但也順便提供一些SQL查詢優化的建議: + 使用批量查詢,而不是N次循環查詢! + 重復的數據,不要重復獲取; + 根據需要,按需要獲取表字段,而不是SELECT *; + 針對頻繁的搜索字段,建立必要的索引,以加快查詢速度; + 使用關聯查詢,而不是粗暴地類似:where uid IN (... 這里是成千上W個用戶ID ...); + 針對單條SQL語句執行時間超過1秒的,重點優化; ##2.13.5 最后最后 奉上我們堅持TDD開發下的單元測試代碼: ```javascript public function testGetMultiBaseInfo() { $str = 'service=User.GetMultiBaseInfo&user_ids=1,2,3'; parse_str($str, $params); DI()->request = new PhalApi_Request($params); $api = new Api_User(); //自己進行初始化 $api->init(); $rs = $api->getMultiBaseInfo(); $this->assertNotEmpty($rs); $this->assertArrayHasKey('code', $rs); $this->assertArrayHasKey('msg', $rs); $this->assertArrayHasKey('list', $rs); foreach ($rs['list'] as $item) { $this->assertArrayHasKey('id', $item); $this->assertArrayHasKey('name', $item); $this->assertArrayHasKey('note', $item); } } ``` 執行單元測試的效果: ```javascript dogstar@ubuntu:Tests$ phpunit --filter testGetMultiBaseInfo ./Api/Api_User_Test.php PHPUnit 4.3.4 by Sebastian Bergmann. . Time: 23 ms, Memory: 6.25Mb OK (1 test, 13 assertions) ``` 搞定,收工,開飯!
                  <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>

                              哎呀哎呀视频在线观看