初識PhalApi(探索接口服務開發(fā)技術)_第1頁
初識PhalApi(探索接口服務開發(fā)技術)_第2頁
初識PhalApi(探索接口服務開發(fā)技術)_第3頁
初識PhalApi(探索接口服務開發(fā)技術)_第4頁
初識PhalApi(探索接口服務開發(fā)技術)_第5頁
已閱讀5頁,還剩404頁未讀 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

初識PhalApi探索接口服務開發(fā)技術目錄\h第一部分探索\h第1章遇見PhalApi\h1.1PhalApi是什么?\h1.2PhalApi的前世今生\h1.2.1前世:個人框架zenphpWS3\h1.2.2今生:開源框架PhalApi\h1.3接口,從簡單開始!\h1.3.1一個隱喻\h1.3.2PhalApi框架所做的\h1.4下載與安裝\h1.5創(chuàng)建一個新項目\h1.6HelloWorld\h1.7對PhalApi框架的抉擇\h1.7.1適用的場景和項目\h1.7.2敏捷開發(fā)和快速交付\h1.7.3約束和關注\h1.7.4復雜領域業(yè)務的應對和解決方案\h1.7.5框架的性能\h1.7.6成熟度與學習成本\h本章小結\h參考資料\h第2章基礎入門\h2.1接口請求\h2.1.1接口服務URI\h2.1.2參數(shù)規(guī)則\h2.2.3過濾器與簽名驗證\h2.2.4擴展你的項目\h2.2接口響應\h2.2.1響應結構\h2.2.2返回格式\h2.2.3領域特定設計與Fiat標準\h2.2.4在線調試\h2.2.5擴展你的項目\h2.3細說ADM模式\h2.3.1何為Api-Domain-Model模式?\h2.3.2會講故事的Api接口層\h2.3.3專注領域的Domain業(yè)務層\h2.3.4廣義的Model數(shù)據(jù)層\h2.3.5ADM職責劃分與調用關系\h2.3.6擴展你的項目\h2.4配置\h2.4.1配置的簡單讀取\h2.4.2配置管理策略\h2.4.3使用Yaconf擴展快速讀取配置\h2.4.4擴展你的項目\h2.5數(shù)據(jù)庫操作\h2.5.1NotORM簡介\h2.5.2數(shù)據(jù)庫配置\h2.5.3Model基類的使用\h2.5.4CURD基本操作\h2.5.5事務操作、關聯(lián)查詢和其他操作\h2.5.6分表分庫策略\h2.5.7擴展你的項目\h2.6緩存策略\h2.6.1簡單本地緩存\h2.6.2高速集群緩存\h2.6.3多級緩存策略\h2.6.4擴展你的項目\h2.7日志\h2.7.1簡化版的日記接口\h2.7.2擴展你的項目\h2.8COOKIE\h2.8.1COOKIE的基本使用\h2.8.2記憶加密升級版\h2.8.3擴展你的項目\h2.9i18n國際化\h2.9.1語言設定\h2.9.2翻譯包\h2.9.3通用的翻譯寫法\h2.9.4擴展你的項目\h本章小結\h參考資料\h第3章高級主題\h3.1讓資源更可控的依賴注入\h3.1.1何為依賴注入?\h3.1.2依賴注入的基本使用\h3.1.3架構明顯的編程風格\h3.1.4依賴注入的好處\h3.1.5DI資源速查表\h3.2PEAR包命名規(guī)范下的自動加載\h3.2.1PEAR包命名規(guī)范\h3.2.2掛靠式自動加載\h3.2.3初始化文件和入口文件的區(qū)別\h3.3自動生成的在線文檔\h3.3.1在線接口列表文檔\h3.3.2在線接口詳情文檔\h3.4接口查詢語言與SDK包\h3.4.1用一句話來描述接口請求\h3.4.2接口查詢語言設計理念與使用示例\h3.4.3更好的建議\h3.4.4Java版SDK包的使用說明\h3.4.5Ruby版SDK包的使用說明\h3.5腳本命令的使用\h3.5.1phalapi-buildapp命令\h3.5.2phalapi-buildtest命令\h3.5.3phalapi-buildsqls命令\h3.5.4phalapi-buildcode命令\h3.6可重用的擴展類庫\h3.6.1擴展類庫簡介\h3.6.2安裝、配置注冊與使用\h3.6.3常用擴展類庫介紹\h3.6.4從微架構到擴展類庫的演進\h3.7超越HTTP/HTTPS協(xié)議\h3.7.1構建RESTfulAPI\h3.7.2使用PHPRPC協(xié)議\h3.7.3利用SOAP搭建WebServices\h3.7.4創(chuàng)建命令行CLI項目\h3.7.5小結\h本章小結\h參考資料\h第4章不只是編碼\h4.1測試驅動開發(fā)\h4.1.1意圖導向編程、原則與模式\h4.1.2在PhalApi下進行TDD的一般步驟\h4.1.3對接口類的三角驗證\h4.1.4“造假”技巧\h4.1.5用一分鐘,盡早發(fā)現(xiàn)問題\h4.1.6小結\h4.2設計模式的應用\h4.2.1形式服從于功能\h4.2.2在項目開發(fā)中的應用\h4.2.3在擴展類庫中的應用\h4.2.4在PhalApi框架中的應用\h4.2.5優(yōu)先考慮最終使用的方式\h4.2.6小結\h4.3小步重構\h4.3.1對過去代碼的優(yōu)化,對將來代碼的雕琢\h4.3.2改善既有的代碼\h4.3.3以模式為指導進行重構\h4.3.4重構這條路\h本章小結\h參考資料\h第二部分\h第5章全新的創(chuàng)業(yè)項目\h5.1項目背景\h5.2如何開啟一個新項目\h5.2.1需求分析與模塊拆分\h5.2.2數(shù)據(jù)庫設計\h5.2.3為項目創(chuàng)建Git代碼倉庫\h5.2.4部署開發(fā)環(huán)境\h5.3具體接口服務開發(fā)\h5.3.1制定接口規(guī)范\h5.3.2日歷事件模塊的三個接口服務\h5.2.3日歷事件接口服務的開發(fā)\h5.3.4查看日歷事件列表接口服務的開發(fā)\h5.3.5操作日歷事件接口服務的開發(fā)\h5.3.6圖片上傳接口服務的開發(fā)\h5.3.7在完成的基礎上追求完美\h5.3.8再談單元測試驅動開發(fā)\h5.4與客戶端的聯(lián)調\h5.4.1與移動App的聯(lián)調\h5.4.2與管理后臺的聯(lián)調\h5.5上線發(fā)布\h5.5.1上線checklist\h5.5.2通過FTP或其他方式發(fā)布\h5.2.3發(fā)布驗收\h5.6項目小結\h第6章重寫歷史遺留項目\h6.1項目背景\h6.2重寫歷史遺留項目的前期準備\h6.2.1數(shù)據(jù)庫遷移\h6.2.2剖析已有的接口系統(tǒng)\h6.3新接口系統(tǒng)的設計\h6.3.1客戶端接入規(guī)范\h6.3.2服務端開發(fā)規(guī)范\h6.3.3多入口,多模塊\h6.3.4通過系統(tǒng)變量維護服務器配置\h6.3.5在線接口文檔\h6.3.6擴展類庫的應用\h6.4重寫既有的接口服務\h6.4.1數(shù)據(jù)庫分表\h6.4.2用特征草圖分解“萬能類”\h6.4.3消化復雜的領域業(yè)務\h6.5開發(fā)新增的接口服務\h6.5.1有趣的體重數(shù)據(jù)\h6.5.2善于解決復雜問題的設計模式\h6.5.3如何測試耗時的計劃任務\h6.5精益求精\h6.5.1獲取家庭圈信息的接口服務\h6.5.2使用Xhprof剖析性能\h6.5.3Autobench壓力測試與高效緩存\h6.5.3通過Phing進行版本的發(fā)布與回滾\h6.6成果回顧\h第7章一個極致的項目\h7.1項目背景\h7.2Api接口層的規(guī)范\h7.2.1一個接口服務,一個文件\h7.2.2更簡單請求的形式\h7.2.3參數(shù)規(guī)則配置\h7.2.4接口實現(xiàn)與返回規(guī)范\h7.2.5注釋規(guī)范與自動生成文檔\h7.3Domain領域層的規(guī)范\h7.3.1實體\h7.3.2服務\h7.3.3值對象\h7.4Model數(shù)據(jù)層的規(guī)范\h7.4.1常見的關系型數(shù)據(jù)庫對接\h7.4.2NoSQL陣容\h7.4.3遠程接口的調用\h7.4.4一切皆文件\h7.5這只個開始\h第三部分再進一步\h第8章PhalApi完美詮釋\h8.1核心設計講解\h8.1.1共性和可變性分析回顧\h8.12解讀主流程\h8.1.3UML靜態(tài)類結構\h8.2性能剖析\h8.2.1Xhprof性能報告\h8.2.2Ab基準測試\h8.3靜態(tài)代碼質量\h8.3.1Sonar分析報告\h8.3.2PHPMetrics分析報告\h8.4追求極致的單元測試\h8.5DI與擴展類庫\h8.5.1再談DI依賴注入\h8.5.2可重用的擴展類庫\h8.6PhalApi內省\h本章小結\h第9章如何有效設計接口框架\h9.1正統(tǒng)\h9.1.1定位\h9.1.2正名\h9.2在開始之前\h9.2.1揣測它的使用\h9.2.2如何用于開發(fā)?\h9.2.3異常,擴展與不確定性\h9.2.4忠于自己\h9.3吾有框架初成形\h9.3.1SOLID原則與穩(wěn)定依賴\h9.3.2協(xié)作與交流\h9.3.3論編程范式\h9.4精雕細琢\h9.4.1可測試性\h9.4.2性能之巔\h9.4.3代碼質量\h9.4.4從優(yōu)秀到卓越\h9.5有效交付\h9.5.1幫助用戶認識新框架\h9.5.2文檔\h9.5.3HelloWorld示例\h本章小節(jié)\h10開源這條路\h10.1這是一個美好時代\h10.2為什么要開源?\h10.2.1因為興趣\h10.2.2因為擔當\h10.3離不開的Linux\h10.3.1開源\h10.3.2技術\h10.3.3文化\h10.4領域再細分\h10.4.1編程語言\h10.4.2開源框架\h10.4.3接口框架\h10.5PhalApi開源回顧\h10.5.1初為人知\h10.5.2自建社區(qū)\h10.5.3文檔,博客,視頻\h10.5.4邁向2.x全新版本\h尾聲\h附錄A接口服務文檔模板\h1、功能說明\h2、接口服務URL\h3、接口服務參數(shù)\h4、返回結果\h返回字段\h結果示例\h請求示例

注:原文檔電子版(非掃描),需要的請下載本文檔后留言謝謝。第一部分探索第一部分介紹的是PhalApi的基礎內容,以及高級主題,最后還會講述除了編碼部分,其他的主題。這一部分,我們將探索如何使用PhalApi進行項目開發(fā),從對PhalApi的感性認識,再到細致的基礎開發(fā),最后深入到核心的思想和理念。

第1章遇見PhalApi古云此日足可惜,吾輩更應惜秒陰?!匚洹断r》1.1PhalApi是什么?PhalApi,簡稱:π框架,是一個國產開源的PHP輕量級接口開發(fā)框架,專注于接口服務開發(fā),支持HTTP/SOAP/RPC協(xié)議,可用于快速搭建微服務、RESTful接口或WebServices。1.2PhalApi的前世今生1.2.1前世:個人框架zenphpWS3PhalApi最初是始于2012年個人畢業(yè)論文的項目開發(fā)需要。由于當時課題是開發(fā)一個基于旅游軌跡的圖片分享平臺,需要開發(fā)一套提供給App客戶端使用的后臺服務接口。然而,在實際項目開發(fā)中,發(fā)現(xiàn)身邊很多團隊在使用PHP進行接口開發(fā)時,往往是很簡單,或者說是很粗爆的,如直接使用fopen()函數(shù)獲取遠程接口的執(zhí)行結果再加以處理。尷尬的是,當時在尋找一個可以用于快速后臺接口開發(fā)的PHP框架時,沒找到合適貼切的開源框架。準確來說來,沒找到一個專注于接口開發(fā)的開源框架。基于此,萌生了自主研發(fā)一個接口框架的想法。經過到圖書館和網上查閱整理多方資料、知識和理論,和一段時間的設計及編碼后,便延生了最初的接口框架,并命名為:zenphpWS3。其中,zen表示開源、php表示用PHP開發(fā)、WS表示WebService、3表示支持SOAP、HTTP或RPC三種協(xié)議以及JSON、XML或數(shù)組等多種格式的返回。zenphpWS3很好地支撐畢業(yè)論文項目的開發(fā),并初步具備了一個框架的基本特質與思想。但經過一年的全職工作,以及學習、研究眾多優(yōu)秀開源構架后,發(fā)現(xiàn)還存在很多有待改善的地方。所以,當再次使用zenphpWS3進行新接口項目開發(fā)時,我便在開發(fā)具體應用接口服務的同時,也有意識地在對接口框架進行完善和重構,并融入框架所需要的特性、原則和模式。如可重用、IoC、SOILD設計原則、組件和容器等。至此,通過不斷演進迭代,一個更好的接口框架便慢慢浮現(xiàn)了出來。1.2.2今生:開源框架PhalApi與此同時,我們迎來了移動互聯(lián)網的浪潮。很多大的企業(yè)都提供了開放平臺,如騰訊開放平臺、新浪微博開放平臺、優(yōu)酷開放平臺等。而對于中型公司或者初創(chuàng)團隊,則需要為自主的APP開發(fā)提供特定領域業(yè)務功能的接口服務。也就是說,越來越多的項目需要像我當初那樣開發(fā)接口服務,但也可能同樣會像我當初那樣面臨找不到合適貼切開源框架的困境。秉著希望能幫助更多同學快速開發(fā)接口項目的初衷,我便再次對此接口框架進行重構優(yōu)化,于2015年正式走向開源,并更名為:PhalApi,簡稱:π框架。正如PHPUnit的作者SebastianBergmann所說的那樣:Drivenbyhispassiontohelpdevelopersbuildbettersoftware.同樣,我們希望通過PhalApi,可以:一來,支撐輕量級接口項目的快速開發(fā);二來,闡明如何更好地進行接口開發(fā)、設計和維護;三來,分享優(yōu)秀的編程思想、實用的工具和精益求精的技藝。最初的接口框架就在這樣的背景和研究下出來了。1.3接口,從簡單開始!1.3.1一個隱喻假設我們有一條這樣的表達式:1+1=2

顯然,這是非常簡單,且易于理解的。但倘若我們在中間添加一些復雜性后:1+(96-867+700-6+7-30/10+100-27)+1=2

同樣可以獲得相同的結果,但表達卻羞澀難懂,且容易出錯。你可能會覺得好笑:怎么可能會有人把這么簡單的問題復雜化呢?還編寫這么累贅的代碼?然而,如果你回顧一下以往接觸過的項目或留意一下身邊正在運行的代碼,你會發(fā)現(xiàn),這種情況是真實存在的。在不同的領域開發(fā)不同的項目,各自需求不同,所編寫的代碼也就不盡相同??v使這樣,即使我們不能把代碼簡化到最理想的狀態(tài),但至少可以通過努力以達到“編寫人容易理解的代碼”這一最佳狀態(tài)。一如這樣:1+(0)+1=2

1.3.2PhalApi框架所做的使用PhalApi框架進行接口項目開發(fā),我們不能保證最終編寫出來的項目代碼一定會“短而美”,因為更多的代碼編寫來自于你雙手的輸入、來自你自己切身的思考和設計。但我們希望PhalApi可以在支持接口快速開發(fā)的基礎上,為你和更多開發(fā)團隊提供關于接口項目開發(fā)的一些技藝、參考和幫助。所以,與其他很多關注服務器性能的框架不同,PhalApi更加關注的是人的心情、開發(fā)效率和團隊合作,而這些正是通過約束與規(guī)范、測試驅動開發(fā)、自動化工具、持續(xù)集成和敏捷開發(fā)等途徑可以達成的。這一切一切,都要從代碼的編寫開始。畢竟我們作為專業(yè)軟件開發(fā)人士,代碼是我們連接世界的媒介。而接口代碼的編寫,又應從簡單開始。泡一杯咖啡,讓我們開始吧。1.4下載與安裝PhalApi框架的最新版本的代碼,可以到Github進行下載。/phalapi/phalapi

也可以到國內的碼云上進行下載。/dogstar/PhalApi

這兩個倉庫的代碼會同步一致,開發(fā)人員可根據(jù)自己的喜歡選擇使用。其中,release分支為中文穩(wěn)定版;release-en分支為英文穩(wěn)定版。需要使用PHP5.3.3及以上版本。安裝如同其他的框架一樣,將下載的框架壓縮包上傳到服務器后解壓即可。結合自己的喜愛與項目需要,可以采用Apache、XAMPP、MicrosoftIIS等。根據(jù)使用的服務器不同,配置也不一樣。本書所使用的環(huán)境是:PHP5.3.10Nginx1.1.19PhalApi1.4.0Ubuntu12.04(64位)所以在這里,本書統(tǒng)一約定使用PhaApi1.4.0版本,并且推薦使用Nginx作為服務器。以這里的環(huán)境安裝為例,假設框架解壓的目錄為:/path/to/PhalApi/Public,則首先需要添加Nginx配置文件,然后重啟Nginx,最后添加HOST并訪問。即首先,新建一個配置文件:#vim/etc/nginx/sites-available/

并添加以下參考配置:server{

listen80;

server_name;

root/path/to/PhalApi/Public;

charsetutf-8;

location/{

indexindex.htmlindex.htmindex.php;

}

location~\.php${

fastcgi_split_path_info^(.+\.php)(/.+)$;

fastcgi_pass:9000;

fastcgi_indexindex.php;

includefastcgi_params;

fastcgi_paramSCRIPT_FILENAME$document_root$fastcgi_script_name;

}

access_loglogs/.access.log;

error_loglogs/.error.log;

}

接著,創(chuàng)建軟鏈:#ln-s/etc/nginx/sites-available//etc/nginx/sites-enabled/

重啟Nginx服務:$/etc/init.d/nginxrestart

并在服務器的/etc/hosts文件里添加:

最后在瀏覽器訪問Demo的默認接口服務,測試接口是否可以正常訪問,如請求:/demo/

正常情況下,會看到類似以下這樣的返回結果。{

"ret":200,

"data":{

"title":"HelloWorld!",

"content":"PHPer您好,歡迎使用PhalApi!",

"version":"1.4.0",

"time":1492346885

},

"msg":""

}

溫馨提示:為了可視化JSON結果,Chrome瀏覽器可安裝JSONView擴展,F(xiàn)irefox可以安裝JSON-handel擴展。1.5創(chuàng)建一個新項目安裝好后,可以使用在線可視化安裝向導來創(chuàng)建一個新的項目。安裝向導在目錄./Public/install/下,在瀏覽器輸入/install/便可訪問此安裝向導。安裝界面如下:圖1-1安裝向導隨后按照提示,一步步操作即可。創(chuàng)建新項目過程,會要求輸入項目名稱。假設我們需要為商城創(chuàng)建一個項目,并命名為:shop,那么安裝完成后訪問效果如下。圖1-2新建shop項目的運行效果這時,可以看到新建了以下目錄和文件。$tree./Shop/./Public/shop/

./Shop/

├──Api

│└──Default.php

├──Common

├──Domain

├──Model

└──Tests

./Public/shop/

├──checkApiParams.php

├──index.php

└──listAllApis.php

對于各個目錄,簡單說明如下:./Shop:放置項目源代碼,每個項目對應一個目錄./Shop/Api:接口服務類目錄./Shop/Domain:領域業(yè)務類目錄./Shop/Model:數(shù)據(jù)模型類目錄./Shop/Common:公共目錄./Shop/Tests:單元測試目錄以上都是外界不可直接訪問的目錄,下面則是對外可訪問的目錄和文件。./Public/shop:外部可訪問的目錄./Public/shop/index.php:入口文件./Public/shop/listAllApis.php:在線接口列表文檔./Public/shop/checkApiParams.php:在線接口詳情文檔關于各個目錄和各個文件的作用,后續(xù)會作進一步說明。至此,我們已經取到了階段性的成果。我們完成了框架的安裝與部署,還創(chuàng)建了一個新的項目。接下來,讓我們繼續(xù)探索一下,如何在PhalApi下進行具體的接口編碼開發(fā)。1.6HelloWorld遵循國際慣例,這里編寫的第一個接口也是HelloWorld。這是一個非常簡單的接口,主要功能是返回“HelloWorld”這串字符。繼續(xù)使用上面已創(chuàng)建的shop項目。首先,創(chuàng)建一個接口類文件./Shop/Api/Welcome.php,并在這里實現(xiàn)主要的功能。//./Shop/Api/Welcome.php

<?php

classApi_WelcomeextendsPhalApi_Api{

publicfunctionsay(){

return'HelloWorld';

}

}

然后,便可以對接口進行訪問了。如最簡單的方式,還是使用瀏覽器來訪問。接口訪問的格式為:接口域名+入口路徑+?service=XXX.XXX,所以此接口服務對應的鏈接為:/shop/?service=Welcome.Say

結果默認以JSON格式返回,即正常情況下會看到:{"ret":200,"data":"HelloWorld","msg":""}

以上代碼和運行結果截圖如下。圖1-3HelloWorld代碼與運行結果是不是發(fā)現(xiàn)接口開發(fā)很簡單?當然,這里只是一個很簡單的HelloWorld示例。實際項目開發(fā)中,所遇到的業(yè)務場景會更為復雜,所面臨的技術挑戰(zhàn)也會更為深奧。雖然是一個簡單示例,但也很好地幫助了我們對PhalApi的開發(fā)和使用有了感性的認識,同時察覺到在進行接口開發(fā)時需要時刻保持前瞻性和注重細節(jié)。例如細心的讀者會發(fā)現(xiàn),這里返回的是一個字符串,若日后需要在這個接口添加其他字段的返回則難以保持向前兼容性。所以,離細致的接口開發(fā),我們還有一段路要走。希望這本書,可以陪你更好、更順暢、更愉悅地度過這段美妙的旅途!1.7對PhalApi框架的抉擇能使用框架來進行項目開發(fā),和知道為何使用此框架進行項目開發(fā)明顯不同。對框架的選擇,名義上是架構師的職責,但對于充滿好奇心和有著更強求知欲的開發(fā)人員來說,同樣應該給予關注。之所以選擇一個框架進行項目開發(fā),表面上是為了減少不必要的重復代碼;但更深層次,則是為了減少開發(fā)周期、統(tǒng)一開發(fā)規(guī)范、降低項目風險,最終快速迭代、持續(xù)交付,不致于項目失控。在決定使用PhalApi框架前,對于此框架是否適用于即將啟動的項目進行一番思索,是大有裨益的。通過推定框架,有助于避免因采用不當?shù)目蚣芏鴮椖吭斐刹槐匾淖枇Α?.7.1適用的場景和項目PhalApi框架特別適用于當前為各移動App或其他后臺系統(tǒng)開發(fā)遠程接口服務。可用于搭建高訪問量、大數(shù)據(jù)存儲的接口項目,可以掛靠多個接口項目,也可以很好地支持多個終端、多個版本、多個訪問入口。此外,還提供各種可重用的擴展類庫,便于快速開發(fā)。基于此,我們采用了主流設計,即將框架設計成默認使用HTTP協(xié)議訪問,并以JSON格式返回請求結果。因為HTTP協(xié)議和JSON格式,都是當前大眾所熟悉的。1.7.2敏捷開發(fā)和快速交付雖然框架和工程實踐間沒有必然的聯(lián)系,但我想其中應該會有一些微妙的聯(lián)系。一種代碼編寫的方式會形成一種開發(fā)的風格;一種開發(fā)風格會奠定一個團隊的合作氛圍;一個團隊的合作氛圍會決定項目交付的質量。而PhalApi所提倡和希望做到的正是通過讓接口開發(fā)更簡單,讓后臺開發(fā)人員心情更愉悅,從而為客戶端提供高質量的接口服務。此外,結合重構、測試驅動開發(fā)和持續(xù)集成等,可以讓你的項目如虎添翼,在快速交付的同時,體驗編碼開發(fā)的樂趣。1.7.3約束和關注架構約束程序。約束有時會讓開發(fā)者處處受阻。但好的約束能夠統(tǒng)一規(guī)范而不致于項目代碼凌亂不堪,也不會輕易地允許低級開發(fā)新手犯下一些本可避免的BUG。正如,我們都討厭等待紅綠燈,但我們必須肯定它對交通和生命安全保障的作用。1.7.4復雜領域業(yè)務的應對和解決方案正如前面說到的,我們關注在海量數(shù)據(jù)下為移動App提供穩(wěn)定的接口,我們提倡敏捷開發(fā)下的快速交付。所以我們去掉與接口開發(fā)無關的功能,沒有提供視圖渲染和模板解析的操作。但只是這樣而已嗎?不!我們還關注對復雜領域業(yè)務的應對和解決方案。如果我們PhalApi框架所關注的,也是你們項目所關注的,那么我們有理由相信PhalApi能為你的項目帶來很多友好的約束和貼心的幫助。1.7.5框架的性能很多框架都要強調其能提供的性能,然后PHP本身就是動態(tài)的腳本語言,要想提高項目的運行速度,就是要進行減法,即減少不必要的PHP代碼。但是前面強調性能的框架則做了與其承諾矛盾的做法:為框架增添了很多項目可能不需要用到的功能。明顯地就是一系列既定的執(zhí)行流程和偵聽事件、回調、調度等等。而這些,勢必會對性能有所影響,特別當應用項目不需要這些特性卻又不能定制簡化時,框架所謂的強悍功能會適得其反。對于這一塊,我們則提供了極大的空間。因為,入口和初始化文件,我們可以自由定制。除了一些必要的加載外,很多都可以支持自定義和定制化。而且我們也使用Autobench進行了壓力測試和通過XHprof進行了性能剖析,證明PhalApi框架在性能上確實如我們預料的那樣——快!1.7.6成熟度與學習成本不可否認,PhalApi還是太年輕了。PhalApi正式開源于2015年1月,但是我們一直都在努力完善,我們盡量“減少不必要的創(chuàng)新”,我們堅持像恒星一般完美支持框架升級,我們盡量提供優(yōu)秀的文檔、及時的溝通和技術幫助。更為重要的是,這是一個不只為框架而框架的PhalApi框架?!叭朔ǖ兀胤ㄌ?,天法道,道法自然”。以前經常聽說老子這句話,但對于其中的意思最初是不明白的,甚至誤解的?!胺ā弊郑谶@里是學習、效仿的意思。我則把這句稍微簡化了一下,精簡成:人法自然。在自然界中,無論是石頭縫之間的小草,公園里植物,還是山上的生態(tài)環(huán)境,不管你來不來,它們都一直欣欣而向榮、充滿活力。我們應該學習自然這種品質,忠于自己。PhalApi也一樣,一直在努力成長,保持生氣,為開源社區(qū)負責。不會因為使用的人多了就迷亂,也不會因為使用的人少就停止不前。在開發(fā)過程中,對于PhalApi不能很好解決和支持的問題,你也可以考慮嘗試優(yōu)化框架,將某一目標或屬性提升至架構,其他團隊成員則可從中獲益。相信你會發(fā)現(xiàn),在PhalApi下,你可以輕松做到這一點:小步快跑下的浮現(xiàn)式設計。本章小結PhalApi是一個國產開源的PHP輕量級接口開發(fā)框架,專注于接口服務開發(fā)。對于接口,我們應該從簡單開始!但在決定選擇PhalApi進行項目開發(fā)前,應該先評估一番,看下此框架是否滿足待開啟的項目的要求。在這一章,我們還學習了PhalApi的下載和安裝,以及如何創(chuàng)建一個新項目,也嘗試編寫了第一個HelloWorld程序。做好了這些準備后,我們便可以踏上新的征途。但在成為一名嫻熟的工匠之前,我們還需要掌握一些基礎知識。接下來——參考資料《恰如其份的框架》推定框架。

《浮現(xiàn)式設計》

第2章基礎入門我發(fā)現(xiàn),我越是努力,就越發(fā)幸運。——ThomasJefferson嫻熟的技藝離不開過硬扎實的基礎。這一章,我們將開始學習PhalApi框架中的基礎內容,包括作為客戶端如何請求接口服務,作為服務端如何返回接口結果,ADM模式的含義和依賴關系,以及其他常用的基礎功能。為避免內容空洞,我們會盡量結合前面的商城項目示例,進行基礎內容的講解。讀者可以在邊學習的過程中,邊實踐操作,加深理解。在每個小節(jié)中,我們會先學習一些基本的使用,以便能滿足普遍項目開發(fā)的技術需要。對于容易誤解、容易出錯的地方,我們會進行溫馨提示,列出注意事項以及提供正確的解決方案。在每個小節(jié)的最后,我們還會再進一步,學習如何擴展項目的能力,定制自己的功能。2.1接口請求PhalApi默認使用的是HTTP/HTTPS協(xié)議進行通訊,請求接口的完整URL格式則是:接口域名+入口路徑+?service=Class.Action+[接口參數(shù)]

其中有應該單獨部署的接口域名,不同項目各自的入口路徑,統(tǒng)一約定的service參數(shù),以及可選的接口參數(shù)。下面分別進行說明。2.1.1接口服務URI接口域名通常,我們建議對于接口服務系統(tǒng),應該單獨部署一個接口域名,而不應與其他傳統(tǒng)的Web應用系統(tǒng)或者管理后臺混合在一起,以便分開維護。假設我們已經有一個站點,其域名為:,現(xiàn)需要為開發(fā)一套接口服務提供給移動App使用。直接在已有站點下添加一個入口以提供服務的做法是不推薦的,即不建議接口URI是:/api。推薦的做法是,單獨配置部署一個新的接口域名,如:。當前,我們也可以發(fā)現(xiàn)很多公司都提供了這樣獨立的接口平臺。例如:優(yōu)酷開放平臺:微信公眾號:新浪微博:如第1章中,我們創(chuàng)建的接口項目,其域名為:。入口路徑入口路徑是相對路徑,不同的項目可以使用不同的入口。通常在這里,我們會在部署接口項目時,會把項目對外可訪問的根目錄設置到./Public目錄。這里所說的入口路徑都是相對這個./Public目錄而言的。與此同時,默認使用省略index.php的路徑寫法。為了更好地理解這樣的對應關系,以下是一些示例對應關系。表2-1入口路徑示例對應關系項目精簡的入口路徑完整的入口路徑入口文件位置項目源代碼位置默認的演示項目/demo/Public/demo/index.php./Public/demo/index.php./Demo新建的商城項目/shop/Public/shop/index.php./Public/shop/index.php./Shop如框架自帶的演示項目,其目錄是:./Public/demo,對應的訪問入口路徑是:/demo;而新建的商城Shop項目的目錄是:./Public/shop,則入口路徑是:/shop。這個入口路徑是可選的,也可以直接使用根目錄。如果是這樣,則需要調整./Public/index.php目錄,并且不便于多項目并存的情況。指定接口服務在PhalApi中,我們統(tǒng)一約定使用service參數(shù)來指定所請求的接口服務。通常情況下,此參數(shù)使用GET方式傳遞,即使用$_GET['service'],其格式為:?service=Class.Action。其中Class是對應請求的接口剔除Api_前綴后的類名,Action則是待執(zhí)行的接口類中的方法名。溫馨提示:未指定service參數(shù)時,默認使用?service=Default.Index。如請求默認的接口服務可用?service=Default.Index,則相應會調用Api_Default::Index()這一接口服務;若請求的是?service=Welcome.Say,則會調用Api_Welcome::Say這一接口服務。以下是一些示例。請求默認接口服務,省略service/shop/

等效于請求默認接口服務/shop/?service=Default.Index

請求HelloWorld接口服務/shop/?service=Welcome.Say

接口參數(shù)接口參數(shù)是可選的,根據(jù)不同的接口服務所約定的參數(shù)進行傳遞。可以是GET參數(shù),POST參數(shù),或者多媒體數(shù)據(jù)。未定制的情況下,PhalApi既支持GET參數(shù)又支持POST參數(shù)。如使用GET方式傳遞username參數(shù):$curl"/shop/?service=Default.Index&username=dogstar"

也可以用POST方式傳遞username參數(shù):$curl-d"username=dogstar""/shop/?service=Default.Index"

至此,我們已經基本了解如何對接口服務發(fā)起請求。接下來,讓我們來看下對于接口服務至關重要的要素——接口參數(shù)。2.1.2參數(shù)規(guī)則接口參數(shù),對于接口服務本身來說,是非常重要的。對于外部調用的客戶端來說,同等重要。對于接口參數(shù),我們希望能夠既減輕后臺開發(fā)對接口參數(shù)獲取、判斷、驗證、文檔編寫的痛苦;又能方便客戶端快速調用,明確參數(shù)的意義。由此,我們引入了參數(shù)規(guī)則這一概念,即:通過配置參數(shù)的規(guī)則,自動實現(xiàn)對參數(shù)的獲取和驗證,同時自動生成在線接口文檔。參數(shù)規(guī)則是針對各個接口服務而配置的多維規(guī)則數(shù)組,由PhalApi_Api::getRules()方法返回。其中,參數(shù)規(guī)則數(shù)組的一維下標是接口類的方法名,對應接口服務的Action;二維下標是類屬性名稱,對應在服務端獲取通過驗證和轉換化的最終客戶端參數(shù);三維下標name是接口參數(shù)名稱,對應外部客戶端請求時需要提供的參數(shù)名稱。即:publicfunctiongetRules(){

returnarray(

'接口類方法名'=>array(

'接口類屬性'=>array('name'=>'接口參數(shù)名稱',......),

),

);

}

通常情況下,接口類屬性和接口參數(shù)名稱一樣,但也可以不一樣。一種情況是客戶端的接口參數(shù)名稱慣用下劃線分割,即蛇形(下劃線)命名法,而服務端中則慣用駝峰命名法。例如對于“是否記住我”,客戶端參數(shù)用is_remember_me,服務端用isRememberMe。另一種情況是如果參數(shù)名稱較長,為了節(jié)省移動網絡下的流量,也可以針對客戶端參數(shù)使用有意義的縮寫。如前面的“是否記住我”客戶端縮寫成is_rem_me。在參數(shù)規(guī)則里,可以配置多個接口類方法名,每個方法名的規(guī)則,又可以配置多個接口類屬性,即有多個接口參數(shù)。配置好參數(shù)規(guī)則后,當接口參數(shù)通過驗證后,就可以在接口類方法內,通過類成員屬性獲取相應的接口參數(shù)。一個簡單的示例假設我們現(xiàn)在需要提供一個用戶登錄的接口,接口參數(shù)有用戶名和密碼,那么新增的接口類和規(guī)則如下://$vim./Shop/Api/User.php

<?php

classApi_UserextendsPhalApi_Api{

publicfunctiongetRules(){

returnarray(

'login'=>array(

'username'=>array('name'=>'username'),

'password'=>array('name'=>'password'),

),

);

}

publicfunctionlogin(){

returnarray('username'=>$this->username,'password'=>$this->password);

}

}

當我們請求此接口服務,并類似這樣帶上username和password參數(shù)時:/shop/?service=User.Login&username=dogstar&password=123456

就可以得到這樣的返回結果。{"ret":0,"data":{"username":"dogstar","password":"123456"},"msg":""}

這是因為,在接口實現(xiàn)類里面getRules()成員方法配置參數(shù)規(guī)則后,便可以通過類屬性的方式,根據(jù)配置指定的名稱獲取對應的接口參數(shù),如這里的:$this->username和$this->password。更完善的示例在實際項目開發(fā)中,我們需要對接口參數(shù)有更細致的規(guī)定,如是否必須、長度范圍、最值和默認值等。繼續(xù)上面的業(yè)務場景,用戶登錄接口服務的用戶名參數(shù)和密碼參數(shù)皆為必須,且密碼長度至少為6個字符,則可以參數(shù)規(guī)則調整為://$vim./Shop/Api/User.php

publicfunctiongetRules(){

returnarray(

'login'=>array(

'username'=>array('name'=>'username','require'=>true),

'password'=>array('name'=>'password','require'=>true,'min'=>6),

),

......

配置好后,如果不帶任何參數(shù)再次請求?service=User.Login,就會被視為非法請求,并得到這樣的錯誤提示:{

"ret":400,

"data":[],

"msg":"非法請求:缺少必要參數(shù)username"

}

如果傳遞的密碼長度不對,也會得到一個錯誤的返回。溫馨提示:當接口參數(shù)非法時,返回的ret都為400,且data為空。在這一章節(jié)中,當再次非法返回時,將省略ret與data,以節(jié)省篇幅。三級參數(shù)規(guī)則配置參數(shù)規(guī)則主要有三種,分別是:系統(tǒng)參數(shù)規(guī)則、應用參數(shù)規(guī)則、接口參數(shù)規(guī)則。系統(tǒng)參數(shù)是指被框架保留使用的參數(shù)。目前已被PhalApi占用的系統(tǒng)參數(shù)只有一個,即:service參數(shù)。類型為字符串,格式為:Class.Action,首字母不區(qū)分大小寫,建議統(tǒng)一以大寫開頭。以下是一些示例:推薦寫法,類名和方法名開頭大寫?service=User.Login

正確寫法,類名和方法名開頭都小寫,或方法名全部小寫?service=user.login

?service=user.getbaseinfo

錯誤寫法,缺少方法名、缺少點號分割、使用豎線而非點號分割?service=User

?service=UserLogin

?service=User|GetBaseInfo

溫馨提示:service參數(shù)中的類名只能開頭小寫,否則會導致linux系統(tǒng)下類文件加載失敗。應用參數(shù)是指在一個接口系統(tǒng)中,全部項目的全部接口都需要的參數(shù),或者通用的參數(shù)。假如我們的商城接口系統(tǒng)中全部的接口服務都需要必須的簽名sign參數(shù),以及非必須的版本號,則可以在./Config/app.php中的apiCommonRules進行應用參數(shù)規(guī)則的配置://$vim./Config/app.php

<?php

returnarray(

/**

*應用接口層的統(tǒng)一參數(shù)

*/

'apiCommonRules'=>array(

//簽名

'sign'=>array(

'name'=>'sign','require'=>true,

),

//客戶端App版本號,默認為:1.4.0

'version'=>array(

'name'=>'version','default'=>'1.4.0',

),

),

......

其配置格式和前面所說的接口參數(shù)規(guī)則配置類似,都是一個規(guī)則數(shù)組。區(qū)別是這里是二維數(shù)組,相當于全部方法的公共的接口類屬性。接口參數(shù)是指各個具體的接口服務所需要的參數(shù),為特定的接口服務所持有,獨立配置。并且進一步在內部又細分為兩種:通用接口參數(shù)規(guī)則:使用*作為下標,對當前接口類全部的方法有效。指定接口參數(shù)規(guī)則:使用方法名作為下標,只對接口類的特定某個方法有效。例如為了加強安全性,需要為全部的用戶接口服務都加上長度為4位的驗證碼參數(shù)://$vim./Shop/Api/User.php

publicfunctiongetRules(){

returnarray(

'*'=>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),

),

);

}

現(xiàn)在,當再次請求用戶登錄接口,除了要提供用戶名和密碼外,我們還要提供驗證碼code參數(shù)。并且,對于Api_User類的其他方法也一樣。多個參數(shù)規(guī)則時的優(yōu)先級當同一個參數(shù)規(guī)則分別在應用參數(shù)、通用接口參數(shù)及指定接口參數(shù)出現(xiàn)時,后面的規(guī)則會覆蓋前面的,即具體化的規(guī)則會替換通用的規(guī)則,以保證接口參數(shù)滿足特定場合的定制要求。簡而言之,多個參數(shù)規(guī)則的優(yōu)先級從高到下,分別是(正如你想到的那樣):1、指定接口參數(shù)規(guī)則2、通用接口參數(shù)規(guī)則3、應用參數(shù)規(guī)則4、系統(tǒng)參數(shù)規(guī)則(通常忽略,當前只有service)參數(shù)規(guī)則配置具體的參數(shù)規(guī)則,根據(jù)不同的類型有不同的配置選項,以及一些公共的配置選項。目前,主要的類型有:字符串、整數(shù)、浮點數(shù)、布爾值、時間戳/日期、數(shù)組、枚舉類型、文件上傳和回調函數(shù)。表2-2參數(shù)規(guī)則選項一覽表類型type參數(shù)名稱name是否必須require默認值default最小值min,最大值max更多配置選項(無特殊說明,均為可選)字符串stringTRUE/FALSE,默認FALSE應為字符串可選regex選項用于配置正則匹配的規(guī)則;format選項用于定義字符編碼的類型,如utf8、gbk、gb2312等整數(shù)intTRUE/FALSE,默認FALSE應為整數(shù)可選浮點數(shù)floatTRUE/FALSE,默認FALSE應為浮點數(shù)可選布爾值booleanTRUE/FALSE,默認FALSEtrue/false以下值會轉換為TRUE:ok,true,success,on,yes,1,以及其他PHP作為TRUE的值時間戳/日期dateTRUE/FALSE,默認FALSE日期字符串可選,僅當為format配置為timestamp時才判斷,且最值應為時間戳format選項用于配置格式,為timestamp時會將字符串的日期轉換為時間戳數(shù)組arrayTRUE/FALSE,默認FALSE字符串或者數(shù)組,為非數(shù)組會自動轉換/解析成數(shù)組可選,判斷數(shù)組元素個數(shù)format選項用于配置數(shù)組和格式,為explode時根據(jù)separator選項將字符串分割成數(shù)組,為json時進行JSON解析枚舉enumTRUE/FALSE,默認FALSE應為range選項中的某個元素必須的range選項,為一數(shù)組,用于指定枚舉的集合文件fileTRUE/FALSE,默認FALSE數(shù)組類型可選,用于表示文件大小范圍,單位為Brange選項用于指定可允許上傳的文件類型;ext選項用于表示需要過濾的文件擴展名回調callable/callbackTRUE/FALSE,默認FALSEcallable/callback選項用于設置回調函數(shù),params選項為回調函數(shù)的第三個參數(shù)(另外第一個為參數(shù)值,第二個為所配置的規(guī)則)公共配置選項公共的配置選項,除了上面的類型、參數(shù)名稱、是否必須、默認值,還有說明描述、數(shù)據(jù)來源。下面分別簡單說明。類型type

用于指定參數(shù)的類型,可以是string、int、float、boolean、date、array、enum、file、callable,或者自定義的類型。未指定時,默認為字符串。參數(shù)名稱name

接口參數(shù)名稱,即客戶端需要傳遞的參數(shù)名稱。與PHP變量規(guī)則一樣,以下劃線或字母開頭。此選項必須提供,否則會提示錯誤。是否必須require

為TRUE時,表示此參數(shù)為必須值;為FALSE時,表示此參數(shù)為可選。未指定時,默認為FALSE。默認值default

未提供接口參數(shù)時的默認值。未指定時,默認為NULL。最小值min,最大值max

部分類型適用。用于指定接口參數(shù)的范圍,比較時采用的是閉區(qū)間,即范圍應該為:[min,max]。也可以只使用min或max,若只配置了min,則表示:[min,+∞);若只配置了maz,則表示:(-∞,max]。說明描述desc

用于自動生成在線接口詳情文檔,對參數(shù)的含義和要求進行扼要說明。未指定時,默認為空字符串。數(shù)據(jù)來源source

指定當前單個參數(shù)的數(shù)據(jù)來源,可以是post、get、cookie、server、request、header、或其他自定義來源。未指定時,默認為統(tǒng)一數(shù)據(jù)源。目前支持的source與對應的數(shù)據(jù)源映射關系如下:表2-3source與對應的數(shù)據(jù)源映射關系source對應的數(shù)據(jù)源post$_POSTget$_GETcookie$_COOKIEserver$_SERVERrequest$_REQUESTheader$_SERVER['HTTP_X']通過source參數(shù)可以輕松、更自由獲取不同來源的參數(shù)。以下是一些常用的配置示例。//獲取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":"服務器運行錯誤:參數(shù)規(guī)則中未知的數(shù)據(jù)源:NOT_FOUND"

9種參數(shù)類型對于各種參數(shù)類型,結合示例說明如下。字符串string當一個參數(shù)規(guī)則未指定類型時,默認為string。如最簡單的:array('name'=>'username')

溫馨提示:這一小節(jié)的參數(shù)規(guī)則配置示例,都省略了類屬性,以關注配置本身的內容。這樣就配置了一個參數(shù)規(guī)則,接口參數(shù)名字叫username,類型為字符串。一個完整的寫法可以為:array('name'=>'username','type'=>'string','require'=>true,'default'=>'nobody','min'=>1,'max'=>10)

這里指定了為必選參數(shù),默認值為nobody,且最小長度為1個字符,最大長度為10個字符,若傳遞的參數(shù)長度過長,如&username=alonglonglonglongname,則會異常失敗返回:"msg":"非法請求:username.len應該小于等于10,但現(xiàn)在username.len=21"

當需要驗證的是中文的話,由于一個中文字符會占用3個字節(jié)。所以在min和max驗證的時候會出現(xiàn)一些問題。為此,PhalApi提供了format配置選項,用于指定字符集。如:array('name'=>'username','type'=>'string','format'=>'utf8','min'=>1,'max'=>10)

我們還可以使用regex下標來進行正則表達式的驗證,一個郵箱的例子是:array('name'=>'email','regex'=>"/^([0-9A-Za-z\\-_\\.]+)@([0-9a-z]+\\.[a-z]{2,3}(\\.[a-z]{2})?)$/i")

整型int整型即自然數(shù),包括正數(shù)、0和負數(shù)。如通常數(shù)據(jù)庫中的id,即可配置成:array('name'=>'id','type'=>'int','require'=>true,'min'=>1)

當傳遞的參數(shù),不在其配置的范圍內時,如&id=0,則會異常失敗返回:"msg":"非法請求:id應該大于或等于1,但現(xiàn)在id=0"

另外,對于常見的分頁參數(shù),可以這樣配置:array('name'=>'page_num','type'=>'int','min'=>1,'max'=>20,'default'=>20)

即每頁數(shù)量最小1個,最大20個,默認20個。浮點float浮點型,類似整型的配置,此處略。布爾值boolean布爾值,主要是可以對一些字符串轉換成布爾值,如ok,true,success,on,yes,以及會被PHP解析成true的字符串,都會轉換成TRUE。如通常的“是否記住我”參數(shù),可配置成:array('name'=>'is_remember_me','type'=>'boolean','default'=>TRUE)

則以下參數(shù),最終服務端會作為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日期可以按自己約定的格式傳遞,默認是作為字符串,此時不支持范圍檢測。例如配置注冊時間:array('name'=>'register_date','type'=>'date')

對應地,register_date=2015-01-3110:00:00則會被獲取到為:"2015-01-3110:00:00"。當需要將字符串的日期轉換成時間戳時,可追加配置選項'format'=>'timestamp',則配置成:array('name'=>'register_date','type'=>'date','format'=>'timestamp')

則上面的參數(shù)再請求時,則會被轉換成:1422669600。此時作為時間戳,還可以添加范圍檢測,如限制時間范圍在31號當天:array('name'=>'register_date','type'=>'date','format'=>'timestamp','min'=>1422633600,'max'=>1422719999)

當配置的最小值或最大值為字符串的日期時,會自動先轉換成時間戳再進行檢測比較。如可以配置成:array('name'=>'register_date',......'min'=>'2015-01-3100:00:00','max'=>'2015-01-3123:59:59')

數(shù)組array很多時候在接口進行批量獲取時,都需要提供一組參數(shù),如多個ID,多個選項。這時可以使用數(shù)組來進行配置。如:array('name'=>'uids','type'=>'array','format'=>'explode','separator'=>',')

這時接口參數(shù)&uids=1,2,3則會被轉換成:array(0=>'1',1=>'2',2=>'3',)

如果設置了默認值,那么默認值會從字符串,根據(jù)相應的format格式進行自動轉換。如:array(......'default'=>'4,5,6')

那么在未傳參數(shù)的情況下,自動會得到:array(0=>'4',1=>'5',2=>'6',)

又如接口需要使用JSON來傳遞整塊參數(shù)時,可以這樣配置:array('name'=>'params','type'=>'array','format'=>'json')

對應地,接口參數(shù)¶ms={"username":"test","password":"123456"}則會被轉換成:array('username'=>'test','password'=>'123456',)

溫馨提示:使用JSON傳遞參數(shù)時,建議使用POST方式傳遞。若使用GET方式,須注意參數(shù)長度不應超過瀏覽器最大限制長度,以及URL編碼問。若使用JSON格式時,設置了默認值為:array(......'default'=>'{"username":"dogstar","password":"xxxxxx"}')

那么在未傳參數(shù)的情況下,會得到轉換后的:array('username'=>'dogstar','password'=>'xxxxxx',)

特別地,當配置成了數(shù)組卻未指定格式format時,接口參數(shù)會轉換成只有一個元素的數(shù)組,如接口參數(shù):&name=test,會轉換成:array(0=>'test')

枚舉enum在需要對接口參數(shù)進行范圍限制時,可以使用此枚舉型。如對于性別的參數(shù),可以這樣配置:array('name'=>'sex','type'=>'enum','range'=>array('female','male'))

當傳遞的參數(shù)不合法時,如&sex=unknow,則會被攔截,返回失?。?msg":"非法請求:參數(shù)sex應該為:female/male,但現(xiàn)在sex=unknow"

關于枚舉類型的配置,這里需要特別注意配置時,應盡量使用字符串的值。因為通常而言,接口通過GET/POST方式獲取到的參數(shù)都是字符串的,而如果配置規(guī)則時指定范圍用了整型,會導致底層規(guī)則驗證時誤判。例如接口參數(shù)為&type=N,而接口參數(shù)規(guī)則為:array('name'=>'type','type'=>'enum','range'=>array(0,1,2))

則會出現(xiàn)以下這樣的誤判:var_dump(in_array('N',array(0,1,2)));//結果為true,因為'N'==0

為了避免這類情況發(fā)生,應該使用使用字符串配置范圍值,即可這樣配置:array('name'=>'type','type'=>'enum','range'=>array(`0`,`1`,`2`))

文件file在需要對上傳的文件進行過濾、接收和處理時,可以使用文件類型,如:array(

'name'=>'upfile',

'type'=>'file',

'min'=>0,

'max'=>1024*1024,

'range'=>array('image/jpeg','image/png'),

'ext'=>array('jpeg','png')

)

其中,min和max分別對應文件大小的范圍,單位為字節(jié);range為允許的文件類型,使用數(shù)組配置,且不區(qū)分大小寫。如果成功,返回的值對應的是$_FILES["upfile"],即會返回:array(

'name'=>...,//被上傳文件的名稱

'type'=>...,//被上傳文件的類型

'size'=>...,//被上傳文件的大小,以字節(jié)計

'tmp_name'=>...,//存儲在服務器的文件的臨時副本的名稱

)

對應的是:$_FILES["upfile"]["name"]-被上傳文件的名稱$_FILES["upfile"]["type"]-被上傳文件的類型$_FILES["upfile"]["size"]-被上傳文件的大小,以字節(jié)計$_FILES["upfile"]["tmp_name"]-存儲在服務器的文件的臨時副本的名稱$_FILES["upfile"]["error"]-由文件上傳導致的錯誤代碼參考:以上內容來自W3School,文件上傳時請使用表單上傳,并enctype屬性使用"multipart/form-data"。更多請參考\hPHP文件上傳。若需要配置默認值default選項,則也應為一數(shù)組,且其格式應類似如上。其中,ext是對文件后綴名進行驗證,當如果上傳文件后綴名不匹配時將拋出異常。文件擴展名的過濾可以類似這樣進行配置:單個后綴名-數(shù)組形式'ext'=>array('jpg')

單個后綴名-字符串形式'ext'=>'jpg'

多個后綴名-數(shù)組形式'ext'=>array('jpg','jpeg','png','bmp')

多個后綴名-字符串形式(以英文逗號分割)'ext'=>'jpg,jpeg,png,bmp'

回調callable/callback當需要利用已有函數(shù)進行自定義驗證時,可采用回調參數(shù)規(guī)則,如配置規(guī)則:array('name'=>'version','type'=>'callable','callback'=>'Common_Request_Version::formatVersion')

然后,回調時將調用下面這個新增的類函數(shù)://$vim./Shop/Common/Request/Version.php

<?php

classCommon_Request_Version{

publicstaticfunctionformatVersion($value,$rule){

if(count(explode('.',$value))<3){

thrownewPhalApi_Exception_BadRequest('版本號格式錯誤');

}

return$value;

}

}

溫馨提示:回調函數(shù)的簽名為:functionformat($value,$rule,$params),第一個為參數(shù)原始值,第二個為所配置的規(guī)則,第三個可選參數(shù)為配置規(guī)則中的params選項。最后應返回轉換后的參數(shù)值。還記得我們前面剛學的三級參數(shù)規(guī)則嗎?雖然在應用參數(shù)配置中已配置公共version參數(shù)規(guī)則,但我們可以在具體的接口類中重新配置這個規(guī)則。把在HelloWorld接口中把這個版本參數(shù)類型修改成此自定義回調類型。即://$vim./Shop/Api/Welcome.php

classApi_WelcomeextendsPhalApi_Api{

publicfunctiongetRules(){

returnarray(

'say'=>array(

'version'=>array('name'=>'version','type'=>'callable','callback'=>'Common_Request_Version::formatVersion'),

)

);

}

......

修改好后,便可使用此自定義的回調處理了。當正常傳遞合法version參數(shù),如請求/shop/welcome/say?version=1.2.3,可以正常響應。若故意傳遞非法的version參數(shù),如請求/shop/welcome/say?version=123,則會提示這樣的錯誤:"msg":"非法請求:版本號格式錯誤"

由于自PHP5.4起可用callable類型指定回調類型callback。所以,為了減輕記憶的負擔,這里使用callable或者callback來表示類型都可以,即可以配置成:'type'=>'callable',,也可以配置成:'type'=>'callback',?;卣{函數(shù)的選項也一樣。以下是來自PHP官網的一些回調函數(shù)的示例://Type1:Simplecallback

call_user_func('my_callback_function');

//Type2:Staticclassmethodcall

call_user_func(array('MyClass','myCallbackMethod'));

//Type3:Objectmethodcall

$obj=newMyClass();

call_user_func(array($obj,'myCallbackMethod'));

//Type4:Staticclassmethodcall(AsofPHP5.2.3)

call_user_func('MyClass::myCallbackMethod');

參考:更多請參考\hCallback/Callable類型。所以上面的callback也可以配置成:'callback'=>array('Common_Request_Version','formatVersion')

2.2.3過濾器與簽名驗證如何開啟過濾器進行簽名驗證?當需要開啟過濾器,只需要注冊DI()->filter即可。在初始化文件init.php中去掉以下注釋便可啟用默認的簽名驗證服務。//$vim./Public/init.php

//簽名驗證服務

DI()->filter='PhalApi_Filter_SimpleMD5';

這里的過濾器是指PhalApi在具體接口服務前所執(zhí)行的過程,主要用于簽名驗證或實現(xiàn)其他預加載處理的功能。默認的簽名方案PhalApi提供了一個默認簽名驗證方案,主要是基于md5的簽名生成。這個只是作為一般性的參考,在實際項目開發(fā)中,我們應該

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論