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

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                # Api接口服務層 **Api接口層**稱為接口服務層,負責對客戶端的請求進行響應,處理接收客戶端傳遞的參數,進行高層決策并對領域業務層進行調度,最后將處理結果返回給客戶端。 ## 接口參數規則配置 接口參數,對于接口服務本身來說,是非常重要的。對于外部調用的客戶端來說,同等重要。對于接口參數,我們希望能夠既減輕后臺開發對接口參數獲取、判斷、驗證、文檔編寫的痛苦;又能方便客戶端快速調用,明確參數的意義。由此,我們引入了**參數規則**這一概念,即:通過配置參數的規則,自動實現對參數的獲取和驗證,同時自動生成在線接口文檔。 ### 一個簡單的示例 假設我們現在需要提供一個用戶登錄的接口,接口參數有用戶名和密碼,那么新增的接口類和規則如下: ```php // 文件 ./src/app/Api/User.php <?php namespace App\Api; use PhalApi\Api; class User extends Api { public function getRules() { return array( 'login' => array( 'username' => array('name' => 'username'), 'password' => array('name' => 'password'), ), ); } public function login() { return array('username' => $this->username, 'password' => $this->password); } } ``` 當請求此接口服務,并類似這樣帶上username和password參數時: ``` /?s=User.Login&username=dogstar&password=123456 ``` 就可以得到這樣的返回結果。 ``` {"ret":0,"data":{"username":"dogstar","password":"123456"},"msg":""} ``` ### 參數規則格式 參數規則是針對各個接口服務而配置的多維規則數組,由接口類的```getRules()```方法返回。其中, + 一維下標是接口類的方法名,對應接口服務的Action; + 二維下標是類屬性名稱,對應在服務端獲取通過驗證和轉換化的最終客戶端參數; + 三維下標```name```是接口參數名稱,對應外部客戶端請求時需要提供的參數名稱。 小結如下: ```php public function getRules() { return array( '接口類方法名' => array( '接口類屬性' => array('name' => '接口參數名稱', ... ... ), ), ); } ``` 在接口實現類里面```getRules()```成員方法配置參數規則后,便可以通過類屬性的方式,根據配置指定的名稱獲取對應的接口參數,如上面的:```$this->username```和```$this->password```。 ### 三級參數規則配置 參數規則主要有三種,分別是:系統參數規則、應用參數規則、接口參數規則。 #### 系統參數 系統參數是指被框架保留使用的參數。目前已被PhalApi占用的系統參數只有一個,即:service參數(縮寫為s參數),前面已有介紹。 #### 應用參數 應用參數是指在一個接口系統中,全部項目的全部接口都需要的參數,或者通用的參數。假如我們的商城接口系統中全部的接口服務都需要必須的簽名sign參數,以及非必須的版本號,則可以在```./config/app.php```中的```apiCommonRules```進行應用參數規則的配置: ```php <?php return array( /** * 應用接口層的統一參數 */ 'apiCommonRules' => array( //簽名 'sign' => array( 'name' => 'sign', 'require' => true, ), //客戶端App版本號,默認為:1.4.0 'version' => array( 'name' => 'version', 'default' => '1.4.0', ), ), ) ``` #### 接口參數 接口參數是指各個具體的接口服務所需要的參數,為特定的接口服務所持有,獨立配置。并且進一步在內部又細分為兩種: + **通用接口參數規則**:使用```*```作為下標,對當前接口類全部的方法有效。 + **指定接口參數規則**:使用方法名作為下標,只對接口類的特定某個方法有效。 例如為了加強安全性,需要為全部的用戶接口服務都加上長度為4位的驗證碼參數: ```php public function getRules() { return array( '*' => array( 'code' => array('name' => 'code', 'require' => true, 'min' => 4, 'max' => 4), ), 'login' => array( 'username' => array('name' => 'username', 'require' => true), 'password' => array('name' => 'password', 'require' => true, 'min' => 6), ), ); } ``` 現在,當再次請求用戶登錄接口,除了要提供用戶名和密碼外,我們還要提供驗證碼code參數。并且,對于Api\User類的其他方法也一樣。 #### 多個參數規則時的優先級 當同一個參數規則分別在應用參數、通用接口參數及指定接口參數出現時,后面的規則會覆蓋前面的,即具體化的規則會替換通用的規則,以保證接口參數滿足特定場合的定制要求。 簡而言之,多個參數規則的優先級從高到下,分別是(正如你想到的那樣): + 1、指定接口參數規則 + 2、通用接口參數規則 + 3、應用參數規則 + 4、系統參數規則 ## 參數規則配置詳細說明 具體的參數規則,根據不同的類型有不同的配置選項,以及一些公共的配置選項。目前,主要的類型有:字符串、整數、浮點數、布爾值、時間戳/日期、數組、枚舉類型、文件上傳和回調函數。 類型 type|參數名稱 name|是否必須 require|默認值 default|最小值 min,最大值 max|更多配置選項(無特殊說明,均為可選) ---|---|---|---|---|--- 字符串|string|TRUE/FALSE,默認FALSE|應為字符串|可選|regex選項用于配置正則匹配的規則;format選項用于定義字符編碼的類型,如utf8、gbk、gb2312等 整數|int|TRUE/FALSE,默認FALSE|應為整數|可選|--- 浮點數|float|TRUE/FALSE,默認FALSE|應為浮點數|可選|--- 布爾值|boolean|TRUE/FALSE,默認FALSE|true/false|---|以下值會轉換為TRUE:ok,true,success,on,yes,1,以及其他PHP作為TRUE的值 時間戳/日期|date|TRUE/FALSE,默認FALSE|日期字符串|可選,僅當為format配置為timestamp時才判斷,且最值應為時間戳|format選項用于配置格式,為timestamp時會將字符串的日期轉換為時間戳 數組|array|TRUE/FALSE,默認FALSE|字符串或者數組,為非數組會自動轉換/解析成數組|可選,判斷數組元素個數|format選項用于配置數組和格式,為explode時根據separator選項將字符串分割成數組, 為json時進行JSON解析 枚舉|enum|TRUE/FALSE,默認FALSE|應為range選項中的某個元素|---|必須的range選項,為一數組,用于指定枚舉的集合 文件|file|TRUE/FALSE,默認FALSE|數組類型|可選,用于表示文件大小范圍,單位為B|range選項用于指定可允許上傳的文件類型;ext選項用于表示需要過濾的文件擴展名 回調|callable/callback|TRUE/FALSE,默認FALSE|---|---|callable/callback選項用于設置回調函數,params選項為回調函數的第三個參數(另外第一個為參數值,第二個為所配置的規則) ### 公共配置選項 公共的配置選項,除了上面的類型、參數名稱、是否必須、默認值,還有說明描述、數據來源。下面分別簡單說明。 + **類型 type** 用于指定參數的類型,可以是string、int、float、boolean、date、array、enum、file、callable,或者自定義的類型。未指定時,默認為字符串。 + **參數名稱 name** 接口參數名稱,即客戶端需要傳遞的參數名稱。與PHP變量規則一樣,以下劃線或字母開頭。此選項必須提供,否則會提示錯誤。 + **是否必須require** 為TRUE時,表示此參數為必須值;為FALSE時,表示此參數為可選。未指定時,默認為FALSE。 + **默認值 default** 未提供接口參數時的默認值。未指定時,默認為NULL。 + **最小值 min,最大值 max** 部分類型適用。用于指定接口參數的范圍,比較時采用的是閉區間,即范圍應該為:[min, max]。也可以只使用min或max,若只配置了min,則表示:[min, +∞);若只配置了maz,則表示:(-∞, max]。 + **說明描述 desc** 用于自動生成在線接口詳情文檔,對參數的含義和要求進行扼要說明。未指定時,默認為空字符串。 + **數據來源 source** 指定當前單個參數的數據來源,可以是post、get、cookie、server、request、header、或其他自定義來源。未指定時,默認為統一數據源。目前支持的source與對應的數據源映射關系如下: source|對應的數據源 ---|--- post | $_POST get | $_GET cookie | $_COOKIE server | $_SERVER request | $_REQUEST header | $_SERVER['HTTP_X'] 通過source參數可以輕松、更自由獲取不同來源的參數。以下是一些常用的配置示例。 ```php // 獲取HTTP請求方法,判斷是POST還是GET 'method' => array('name' => 'REQUEST_METHOD', 'source' => 'server'), // 獲取COOKIE中的標識 'is_new_user' => array('name' => 'is_new_user', 'source' => 'cookie'), // 獲取HTTP頭部中的編碼,判斷是否為utf-8 'charset' => array('name' => 'Accept-Charset', 'source' => 'header'), ``` 若配置的source為無效或非法時,則會拋出異常。如配置了```'source' => 'NOT_FOUND'```,會得到: ``` "msg": "服務器運行錯誤: 參數規則中未知的數據源:NOT_FOUND" ``` ### 9種參數類型 對于各種參數類型,結合示例說明如下。 + **字符串 string** 當一個參數規則未指定類型時,默認為string。如最簡單的: ```php array('name' => 'username') ``` > **溫馨提示:**這一小節的參數規則配置示例,都省略了類屬性,以關注配置本身的內容。 這樣就配置了一個參數規則,接口參數名字叫username,類型為字符串。 一個完整的寫法可以為: ```php array('name' => 'username', 'type' => 'string', 'require' => true, 'default' => 'nobody', 'min' => 1, 'max' => 10) ``` 這里指定了為必選參數,默認值為nobody,且最小長度為1個字符,最大長度為10個字符,若傳遞的參數長度過長,如```&username=alonglonglonglongname```,則會異常失敗返回: ``` "msg": "非法請求:username.len應該小于等于10, 但現在username.len = 21" ``` 當需要驗證的是中文的話,由于一個中文字符會占用3個字節。所以在min和max驗證的時候會出現一些問題。為此,PhalApi提供了format配置選項,用于指定字符集。如: ```php array('name' => 'username', 'type' => 'string', 'format' => 'utf8', 'min' => 1, 'max' => 10) ``` 我們還可以使用```regex```下標來進行正則表達式的驗證,一個郵箱的例子是: ```php array('name' => 'email', 'regex' => "/^([0-9A-Za-z\\-_\\.]+)@([0-9a-z]+\\.[a-z]{2,3}(\\.[a-z]{2})?)$/i") ``` + **整型 int** 整型即自然數,包括正數、0和負數。如通常數據庫中的id,即可配置成: ```php array('name' => 'id', 'type' => 'int', 'require' => true, 'min' => 1) ``` 當傳遞的參數,不在其配置的范圍內時,如```&id=0```,則會異常失敗返回: ``` "msg": "非法請求:id應該大于或等于1, 但現在id = 0" ``` 另外,對于常見的分頁參數,可以這樣配置: ```php array('name' => 'page_num', 'type' => 'int', 'min' => 1, 'max' => 20, 'default' => 20) ``` 即每頁數量最小1個,最大20個,默認20個。 + **浮點 float** 浮點型,類似整型的配置,此處略。 + **布爾值 boolean** 布爾值,主要是可以對一些字符串轉換成布爾值,如ok,true,success,on,yes,以及會被PHP解析成true的字符串,都會轉換成TRUE。如通常的“是否記住我”參數,可配置成: ```php array('name' => 'is_remember_me', 'type' => 'boolean', 'default' => TRUE) ``` 則以下參數,最終服務端會作為TRUE接收。 ``` ?is_remember_me=ok ?is_remember_me=true ?is_remember_me=success ?is_remember_me=on ?is_remember_me=yes ?is_remember_me=1 ``` + **日期 date** 日期可以按自己約定的格式傳遞,默認是作為字符串,此時不支持范圍檢測。例如配置注冊時間: ```php array('name' => 'register_date', 'type' => 'date') ``` 對應地,```register_date=2015-01-31 10:00:00```則會被獲取到為:"2015-01-31 10:00:00"。 當需要將字符串的日期轉換成時間戳時,可追加配置選項```'format' => 'timestamp'```,則配置成: ```php array('name' => 'register_date', 'type' => 'date', 'format' => 'timestamp') ``` 則上面的參數再請求時,則會被轉換成:1422669600。 此時作為時間戳,還可以添加范圍檢測,如限制時間范圍在31號當天: ```php array('name' => 'register_date', 'type' => 'date', 'format' => 'timestamp', 'min' => 1422633600, 'max' => 1422719999) ``` 當配置的最小值或最大值為字符串的日期時,會自動先轉換成時間戳再進行檢測比較。如可以配置成: ```php array('name' => 'register_date', ... ... 'min' => '2015-01-31 00:00:00', 'max' => '2015-01-31 23:59:59') ``` + **數組 array** 很多時候在接口進行批量獲取時,都需要提供一組參數,如多個ID,多個選項。這時可以使用數組來進行配置。如: ```php array('name' => 'uids', 'type' => 'array', 'format' => 'explode', 'separator' => ',') ``` 這時接口參數```&uids=1,2,3```則會被轉換成: ```php array ( 0 => '1', 1 => '2', 2 => '3', ) ``` 如果設置了默認值,那么默認值會從字符串,根據相應的format格式進行自動轉換。如: ```php array( ... ... 'default' => '4,5,6') ``` 那么在未傳參數的情況下,自動會得到: ```php array ( 0 => '4', 1 => '5', 2 => '6', ) ``` 又如接口需要使用JSON來傳遞整塊參數時,可以這樣配置: ```php array('name' => 'params', 'type' => 'array', 'format' => 'json') ``` 對應地,接口參數```&params={"username":"test","password":"123456"}```則會被轉換成: ```php array ( 'username' => 'test', 'password' => '123456', ) ``` > **溫馨提示:**使用JSON傳遞參數時,建議使用POST方式傳遞。若使用GET方式,須注意參數長度不應超過瀏覽器最大限制長度,以及URL編碼問。 若使用JSON格式時,設置了默認值為: ```php array( ... ... 'default' => '{"username":"dogstar","password":"xxxxxx"}') ``` 那么在未傳參數的情況下,會得到轉換后的: ```php array ( 'username' => 'dogstar', 'password' => 'xxxxxx', ) ``` 特別地,當配置成了數組卻未指定格式format時,接口參數會轉換成只有一個元素的數組,如接口參數:```&name=test```,會轉換成: ```php array ( 0 => 'test' ) ``` + **枚舉 enum** 在需要對接口參數進行范圍限制時,可以使用此枚舉型。如對于性別的參數,可以這樣配置: ```php array('name' => 'sex', 'type' => 'enum', 'range' => array('female', 'male')) ``` 當傳遞的參數不合法時,如```&sex=unknow```,則會被攔截,返回失敗: ``` "msg": "非法請求:參數sex應該為:female/male,但現在sex = unknow" ``` 關于枚舉類型的配置,這里需要特別注意配置時,應盡量使用字符串的值。 因為通常而言,接口通過GET/POST方式獲取到的參數都是字符串的,而如果配置規則時指定范圍用了整型,會導致底層規則驗證時誤判。例如接口參數為```&type=N```,而接口參數規則為: ```php array('name' => 'type', 'type' => 'enum', 'range' => array(0, 1, 2)) ``` 則會出現以下這樣的誤判: ```php var_dump(in_array('N', array(0, 1, 2))); // 結果為true,因為 'N' == 0 ``` 為了避免這類情況發生,應該使用使用字符串配置范圍值,即可這樣配置: ```php array('name' => 'type', 'type' => 'enum', 'range' => array(`0`, `1`, `2`)) ``` + **文件 file** 在需要對上傳的文件進行過濾、接收和處理時,可以使用文件類型,如: ```php array( 'name' => 'upfile', 'type' => 'file', 'min' => 0, 'max' => 1024 * 1024, 'range' => array('image/jpeg', 'image/png') , 'ext' => array('jpeg', 'png') ) ``` 其中,min和max分別對應文件大小的范圍,單位為字節;range為允許的文件類型,使用數組配置,且不區分大小寫。 如果成功,返回的值對應的是```$_FILES["upfile"]```,即會返回: ```php array( 'name' => ..., // 被上傳文件的名稱 'type' => ..., // 被上傳文件的類型 'size' => ..., // 被上傳文件的大小,以字節計 'tmp_name' => ..., // 存儲在服務器的文件的臨時副本的名稱 ) ``` 對應的是: + $_FILES["upfile"]["name"] - 被上傳文件的名稱 + $_FILES["upfile"]["type"] - 被上傳文件的類型 + $_FILES["upfile"]["size"] - 被上傳文件的大小,以字節計 + $_FILES["upfile"]["tmp_name"] - 存儲在服務器的文件的臨時副本的名稱 + $_FILES["upfile"]["error"] - 由文件上傳導致的錯誤代碼 > 參考:以上內容來自W3School,文件上傳時請使用表單上傳,并enctype 屬性使用"multipart/form-data"。更多請參考[PHP 文件上傳](http://www.w3school.com.cn/php/php_file_upload.asp)。 若需要配置默認值default選項,則也應為一數組,且其格式應類似如上。 其中,ext是對文件后綴名進行驗證,當如果上傳文件后綴名不匹配時將拋出異常。文件擴展名的過濾可以類似這樣進行配置: + 單個后綴名 - 數組形式 ```php 'ext' => array('jpg') ``` + 單個后綴名 - 字符串形式 ```php 'ext' => 'jpg' ``` + 多個后綴名 - 數組形式 ```php 'ext' => array('jpg', 'jpeg', 'png', 'bmp') ``` + 多個后綴名 - 字符串形式(以英文逗號分割) ```php 'ext' => 'jpg,jpeg,png,bmp' ``` + **回調 callable/callback** 當需要利用已有函數進行自定義驗證時,可采用回調參數規則,如配置規則: ```php array('name' => 'version', 'type' => 'callable', 'callback' => 'App\\Common\\Request\\Version::formatVersion') ``` 然后,回調時將調用下面這個新增的類函數: ```php <?php namespace App\Common\Request; use PhalApi\Exception\BadRequestException; class Version { public static function formatVersion($value, $rule) { if (count(explode('.', $value)) < 3) { throw new BadRequestException('版本號格式錯誤'); } return $value; } } ``` 回調函數的簽名為:```function format($value, $rule, $params)```,第一個為參數原始值,第二個為所配置的規則,第三個可選參數為配置規則中的params選項。最后應返回轉換后的參數值。 ## 接口返回 回顧一下,在PhalApi中,掊口返回的結果的結構為: ```html { "ret": 200, // 狀態碼 "data": { // 業務數據 }, "msg": "" // 錯誤提示信息 } ``` ### 正常情況下的返回 正常情況下,在Api層返回的數據結果,會在返回結果的data字段中體現。例如: ```php class Hello extends Api { public function world() { return array('title' => 'Hello World!'); } } ``` 對應: ``` { "ret": 200, "data": { "title": "Hello World!" }, "msg": "" } ``` 成功返回時,狀態碼ret為200,并且錯誤信息msg為空。 ### 失敗情況下的返回 對于異常情況,包括系統錯誤或者應用層的錯誤,可以通過拋出[PhalApi\Exception](https://github.com/phalapi/kernal/blob/master/src/Exception.php)系列的異常,中斷請求并返回相關的錯誤信息。例如: ```php class Hello extends Api { public function fail() { throw new BadRequestException('簽名失敗', 1); } } ``` 會得到以下結果輸出: ``` { "ret": 401, "data": [], "msg": "Bad Request: 簽名失敗" } ``` ## 注釋與在線文檔 PhalApi提供了自動生成的在線接口文檔,對于每一個接口服務,都有對應的在線接口詳情文檔。如默認接口服務```Site.Index```的在線接口詳情文檔為: ![](http://7xiz2f.com1.z0.glb.clouddn.com/20170716165631_4936f1cf60b99f5f830b4967769cf35b) 此在線接口詳情文檔,從上到下,依次說明如下。 ### 接口服務名稱 接口服務名稱是指用于請求時的名稱,對應s參數(或service參數)。接口服務的中文名稱,為不帶任何注解的注釋,通常為接口類成員函數的第一行注釋。 ```php class Site extends Api { /** * 默認接口服務 */ public function index() { } } ``` ### 接口說明 接口說明對應接口類成員函數的```@desc```注釋。 ```php class Site extends Api { /** * 默認接口服務 * @desc 默認接口服務,當未指定接口服務時執行此接口服務 */ public function index() { } } ``` ### 接口參數 接口參數是根據接口類配置的參數規則自動生成,即對應當前接口類```getRules()```方法中的返回。其中最后的“說明” 字段對應參數規則中的desc選項。可以配置多個參數規則。此外,配置文件./config/app.php中的公共參數規則也會顯示在此接口參數里。 ```php class Site extends Api { public function getRules() { return array( 'index' => array( 'username' => array('name' => 'username', 'default' => 'PHPer', ), ), ); } } ``` ### 返回結果 返回結果對應接口類成員函數的```@return```注釋,可以有多組,格式為:```@return 返回類型 返回字段 說明```。 ```php class Site extends Api { /** * 默認接口服務 * @desc 默認接口服務,當未指定接口服務時執行此接口服務 * @return string title 標題 * @return string content 內容 * @return string version 版本,格式:X.X.X * @return int time 當前時間戳 */ public function index() { } } ``` ### 異常情況 異常情況對應```@exception```注釋,可以有多組,格式為:```@exception 錯誤碼 錯誤描述信息```。例如: ```php /** * @exception 406 簽名失敗 */ public function index() { ``` 刷新后,可以看到新增的異常情況說明。 ### 公共注釋 對于當前類的全部函數成員的公共```@exception```異常情況注釋和```@return```返回結果注釋,可在類注釋中統一放置。而對于多個類公共的@exception```和```@return```注釋,則可以在父類的類注釋中統一放置。 也就是說,通過把```@exception```注解和```@return```注解移到類注釋,可以添加全部函數成員都適用的注解。例如,Api\User類的全部接口都返回code字段,且都返回400和500異常,則可以: ```php <?php namespace App\Api; use PhalApi\Api; /** * @return int code 操作碼,0表示成功 * @exception 400 參數傳遞錯誤 * @exception 500 服務器內部錯誤 */ class User extends Api { ``` 這樣就不需要在每個函數成員的注釋中重復添加注解。此外,也可以在父類的注釋中進行添加。對于相同異常碼的```@exception```注解,子類的注釋會覆蓋父類的注釋,方法的注釋會覆蓋類的注釋;而對于相同的返回結果```@return```注釋,也一樣。 需要注意的是,注釋必須是緊挨在類的前面,而不能是在namespace前面,否則會導致注釋解析失敗。
                  <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>

                              哎呀哎呀视频在线观看