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

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                _一個真正的強者,不是擺平了多少人,而是他能幫助到多少人。 --開源中國源創會分享廣州站 @海洋之心-悟空_ *** ##1.11.1 模擬開發:獲取開源中國用戶信息接口 首次使用此接口開發框架時,可以先查看此開發示例。 假設,我們需要為開源中國打造一個平放平臺,其中有一個接口是可以根據用戶ID來獲取用戶的基本信息。 本文,就以模擬獲取開源中國用戶信息接口開發(即:從數據庫獲取用戶的基本信息并以JSON格式返回給客戶端)為例,簡明的接口開發中的流程,以及用到的基本功能和操作,主要包括有:統一入口文件、參數規則配置、接口層/領域層/模型持久層、日志紀錄、數據庫操作、配置讀取、國際化翻譯等。 以給大家一個感觀的認識。 最終接口的調用與返回結果如下: ```javascript //接口請求格式 http://dev.phalapi.com/demo/?service=User.GetBaseInfo&user_id=帳號ID //返回結果格式 { "ret": 200, "data": { "code": 0, //狀態碼,0表示正常獲取,1表示用戶不存在 "msg": "", "info": { //用戶信息 "id": "1", //用戶ID "name": "dogstar", //帳號 "note": "oschina" //來源 } }, "msg": "" } ``` ##1.11.2 開發流程 ###(1) 統一入口文件 為了更好保護我們的項目代碼,建議將接口的訪問路徑設置在:./PhalApi/Pubic目錄,并且各套接口(如按版本分:v1/v2/v3等等;按不同終端分:ios/android/pc等)各自獨立入口。所以本示例中將./PhalApi/Pubic/demo/index.php下。 參數入口文件的寫法,我們可以快速得到基本的入口文件如下: ```javascript // $ vim ./Public/demo/index.php <?php /** * Demo 統一入口 */ require_once dirname(__FILE__) . '/../init.php'; //裝載你的接口 DI()->loader->addDirs('Demo'); /** ---------------- 響應接口請求 ---------------- **/ $server = new PhalApi(); $rs = $server->response(); $rs->output(); ``` 此外,我們還需要一個公共的初始化文件: ```javascript //$ vim ./Public/init.php <?php /** * 統一初始化 */ /** ---------------- 根目錄定義,自動加載 ---------------- **/ date_default_timezone_set('Asia/Shanghai'); defined('API_ROOT') || define('API_ROOT', dirname(__FILE__) . '/..'); require_once API_ROOT . '/PhalApi/PhalApi.php'; $loader = new PhalApi_Loader(API_ROOT); /** ---------------- 注冊&初始化服務組件 ---------------- **/ //自動加載 DI()->loader = $loader; //配置 DI()->config = new PhalApi_Config_File(API_ROOT . '/Config'); //日志紀錄 DI()->logger = new PhalApi_Logger_File(API_ROOT . '/Runtime', PhalApi_Logger::LOG_LEVEL_DEBUG | PhalApi_Logger::LOG_LEVEL_INFO | PhalApi_Logger::LOG_LEVEL_ERROR); //數據操作 - 基于NotORM,$_GET['__sql__']可自行改名 DI()->notorm = function() { $debug = !empty($_GET['__sql__']) ? true : false; return new PhalApi_DB_NotORM(DI()->config->get('dbs'), $debug); }; //調試模式,$_GET['__debug__']可自行改名 DI()->debug = !empty($_GET['__debug__']) ? true : DI()->config->get('sys.debug'); //翻譯語言包設定 SL('zh_cn'); ``` ###(2)TDD測試驅動開發 遵循最佳實踐,我們在編寫代碼前先編寫單元測試。但同時為了減少編寫測試代碼的痛苦,我們可以先定義接口函數簽名,再通過腳本自動生成測試代碼骨架來提高我們的開發效率。 ```javascript //$vim ./Demo/Api/User.php <?php class Api_User extends PhalApi_Api { public function getBaseInfo() { } } ``` 通過腳本生成測試骨架: ```javascript $ mkdir -p ./Demo/Tests/Api/ $ cd ./Demo/Tests/Api $ php ../../../PhalApi/build_phpunit_test_tpl.php ../../Api/User.php Api_User ./../test_env.php ``` 然后,根據/Public/demo/index.php入口文件,也搭建一個測試環境的入口文件: ```javascript vim ./Demo/Tests/test_env.php ``` 修正一下Api_Examples_User_Test.php里,測試環境test_env.php的包含路徑: ```javascript //手動調用test_env.php的路徑 require_once dirname(__FILE__) . '/../test_env.php'; ``` 并且,修改測試,以符合我們通過userId=1獲取基本信息(名字為dogstar,來源為oschina): ```javascript //$vim ./Demo/Tests/Api/Api_User_Test.php /** * @group testGetBaseInfo */ public function testGetBaseInfo() { $str = 'service=User.GetBaseInfo&user_id=1'; parse_str($str, $params); DI()->request = new PhalApi_Request($params); $api = new Api_User(); //自己進行初始化 $api->init(); $rs = $api->getBaseInfo(); $this->assertNotEmpty($rs); $this->assertArrayHasKey('code', $rs); $this->assertArrayHasKey('msg', $rs); $this->assertArrayHasKey('info', $rs); $this->assertEquals(0, $rs['code']); $this->assertEquals('dogstar', $rs['info']['name']); $this->assertEquals('oschina', $rs['info']['note']); } ``` 此時,單元測試是預期失敗的: ```javascript $ phpunit ./Api_User_Test.php PHPUnit 4.3.4 by Sebastian Bergmann. F Time: 3 ms, Memory: 5.25Mb There was 1 failure: 1) PhpUnderControl_ApiUser_Test::testGetBaseInfo Failed asserting that a NULL is not empty. FAILURES! Tests: 1, Assertions: 1, Failures: 1. ``` ###(3)Api接口層 此接口層,主要是負責響應客戶端的請求,調用需要的領域層進行必要的服務功能提供。 ###配置參數規則 為了獲取到用戶ID,我們可以在getRules()函數里面定義參數規則,以便框架自動幫我們過濾獲取需要的參數。 > 溫馨提示: > 接口層的全部類成員函數都應以小寫開頭。 > 但對外,函數首字母不區分大小寫,因為框架會將請求的函數強制轉換成小寫再執行。 > > 原因在于: > 1、我們堅持駝峰法的代碼風格; > 2、對外界我們可以統一使用大寫來提供服務名稱,如:User.Login,這樣更顯專業。 ```javascript //$vim ./Demo/Api/User.php <?php class Api_User extends PhalApi_Api { public function getRules() { return array( 'getBaseInfo' => array( 'userId' => array('name' => 'userId', 'type' => 'int', 'min' => 1, 'require' => true), ), ); } //... ``` 如上,我們就定義了getBaseInfo接口中的userId參數,名字也為userId,整型,最小值為1,必須。 ####接口實現 ```javascript //$vim ./Demo/Api/User.php public function getBaseInfo() { $rs = array('code' => 0, 'msg' => '', 'info' => array()); $domain = new Domain_User(); $info = $domain->getBaseInfo($this->userId); if (empty($info)) { DI()->logger->debug('user not found', $this->userId); $rs['code'] = 1; $rs['msg'] = T('user not exists'); return $rs; } $rs['info'] = $info; return $rs; } ``` ###(4)Domain領域層 領域層主要是關注復雜業務的處理,以及緩存的處理、耗時操作后臺異步處理等,并調用Model持久層獲取需要的數據。因此,是Api與Model層之間的橋梁。 在此示例中,我們只需要簡單地調用Model層獲取用戶的信息即可,再加強一下用戶ID的合法性判斷。 ```javascript //$ vim ./Demo/Domain/User.php <?php class Domain_User { public function getBaseInfo($userId) { $rs = array(); $userId = intval($userId); if ($userId <= 0) { return $rs; } $model = new Model_User(); $rs = $model->getByUserId($userId); return $rs; } } ``` ###(5)Model持久層 此一層主要關注數據從持久存儲的獲取,特別是針對數據庫的操作,但不排除其他媒介,如文件、緩存等。 首先,先準備一下我們需要的表和數據: ```javascript CREATE TABLE `phalapi_test`.`tbl_user` ( `id` INT NOT NULL, `name` VARCHAR(45) NULL, `note` VARCHAR(45) NULL, PRIMARY KEY (`id`)); INSERT INTO `phalapi_test`.`tbl_user` (`id`, `name`, `note`) VALUES ('1', 'dogstar', 'oschina'); ``` 然后,編寫需要的Model代碼,即利用NotORm實現對數據的操作: ```javascript //$ vim ./Demo/Model/User.php <?php class Model_User { public function getByUserId($userId) { return DI()->notorm->user->select('*')->where('id = ?', $userId)->fetch(); } } ``` ###(6)單元測試通過啦! 在完成上面簡單的開發后,我們即可以實現接口的開發,運行一下剛才的單元測試,完美通過! ```javascript $ phpunit ./Api_User_Test.php PHPUnit 4.3.4 by Sebastian Bergmann. SELECT * FROM tbl_user WHERE (id = ?); -- 1 .SELECT * FROM tbl_user WHERE (id = ?); -- 1<br /> Time: 34 ms, Memory: 6.50Mb OK (2 tests, 7 assertions) ``` 在單元測試的保證下,我們便可以放心大膽地將我們的代碼發布到外網,提供給更多的開發者,和終端用戶使用。 ###(7)數據庫配置 因為是單元測試,所以我們配置搭建了新的一個測試環境,特別對于數據庫的配置,如下: ```javascript //$ vim ./Config/dbs.php <?php /** * examples配置 */ return array( /** * DB數據庫服務器集群 */ 'servers' => array( 'db_demo' => array( 'host' => '192.168.0.104', //數據庫域名 'name' => 'phalapi_test', //數據庫名字 'user' => 'root', //數據庫用戶名 'password' => '123456', //數據庫密碼 'port' => '3306', //數據庫端口 ), ), /** * 自定義路由表 */ 'tables' => array( '__default__' => array( 'prefix' => 'tbl_', 'key' => 'id', 'map' => array( array('db' => 'db_demo'), ), ), ), ); ``` > 溫馨提示: > 為了方便在單元測試時進行調試,和查看日志,對于全部查詢、執行的SQL語句都會顯示出來,全部的日志改用控制臺輸出。 ###(8)最終接口調用 接口調用的鏈接,這時已經相當明了了,即:域名 + 路徑(/demo) + 參數(可從單元測試那直接獲取) 如本示例的是: ```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": "" } ``` 截圖效果: ![show](http://webtools.qiniudn.com/20150411005257_a5d0a984e4dd7fcdd1c95026e337003d) > 溫馨提示: > 如果提示日志寫入失敗,請確保./Runtime目錄具有寫入權限,即0777。 ##1.11.3 更多簡明的使用 ###(1)日志紀錄 當我們訪問一個不存在的用戶時,將會觸發日志紀錄: ```javascript DI()->logger->debug('user not found', $this->userId); ``` 如訪問: ``` http://dev.phalapi.com/demo/?service=User.GetBaseInfo&user_id=2 ``` 然后,可以在Runtime下看到按天分目錄的日志: ```javascript $ tailf ./Runtime/log/201501/20150128.log 2015-01-28 00:37:34|DEBUG|user not found|2 ``` > 溫馨提示: > 外網環境上,請把Runtime目錄軟鏈到磁盤空間很大的路徑。 ###(2)國際化翻譯 當需要翻譯時,可以使用人性化的函數T(),如: ```javascript $rs['msg'] = T('user not exists'); ``` 對應地需要補充翻譯的內容: ```javascript //$ vim ./Language/zh_cn/common.php 'user not exists' => '用戶不存在', ``` 還是以上面的用戶不存在為例,看下運行的截圖效果: ![show](http://webtools.qiniudn.com/20150411005257_d8fc7091e4a2717fa9e1b4f9891117ff) ###(3)配置讀取 配置的讀取,使用方便,直接通過以下方式便可以獲取,以點號分割: ```javascript DI()->config->get('dbs') ``` 第一段,必須為文件名,后面的為用點號相連的數組下標,不限級。 ###(4)[酷!]接口參數在線查詢 為了方便客戶端實時查看最新的接口參數,這里提供了一個快速的在線工具: ```javascript http://dev.phalapi.com/demo/checkApiParams.php?service=User.GetBaseInfo ``` 用瀏覽器打開后,即可以看到最新的接口參數說明, 不需要后臺接口開發人員編寫文檔維護,直接從代碼中生成參數報表: ![show](http://webtools.qiniudn.com/20150411005257_af3f58d9bc050b4906a57fea3d04e9b2) ##1.11.4 Demo相關代碼文件 從上面可以得到,此示例相關的代碼如下: ```javascript Demo$ tree . ├── Api │ ├── Default.php │ └── User.php ├── Domain │ └── User.php ├── Model │ └── User.php └── Tests ├── Api │ ├── Api_Default_Test.php │ └── Api_User_Test.php └── test_env.php ```
                  <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>

                              哎呀哎呀视频在线观看