PhalApi是一款國人制作的PHP純后端框架,它的開發相當簡單,同時也具備檔案生成等特色功能,下面,我通過簡單的幾點,讓你可以快速入門使用該框架的開發,
建議使用PHPStorm作為IDE,代碼提示相當完全,由于PHP的熱更新特性,修改過的PHP檔案保存后立即生效,無需編譯,無需重啟服務器,
什么是PhalApi
PhalApi是一個輕量級的PHP介面框架,有別于傳統的框架,它只面向后端介面的開發,
官網:https://www.phalapi.net
官方檔案:http://docs.phalapi.net/#/v2.0/
安裝PhalApi
Composer是PHP的包管理器(類似于Java的Maven、node的npm),
Composer的安裝請參考https://pkg.phpcomposer.com/#how-to-install-composer,不要在英文官網直接下載安裝包,
Composer安裝后請立即切換到國內源https://developer.aliyun.com/composer,
Phar是PHP界的Jar包,可以像Jar包一樣引入即用,
在專案目錄下執行composer create-project phalapi/phalapi即可創建PhalApi專案,專案路徑為./phalapi,
若需要安裝阿里云OSS的SDK,則在專案路徑下(注意cd到phalapi目錄)按https://help.aliyun.com/document_detail/85580.html說明呼叫Composer,
composer require aliyuncs/oss-sdk-php
composer install
PhalApi提供了再封裝的PhalApi-OSS阿里云OSS包( https://github.com/vivlong/phalapi-aliyun-oss ),也可以考慮使用
本地除錯環境配置
建議使用傻瓜式一體化軟體XAMPP搭建本地的除錯環境,
修改XAMPP中Apache的組態檔,找到這兩行:
DocumentRoot "X:/XAMPP/htdocs"
<Directory "X:/XAMPP/htdocs">
將引號內目錄修改到PhalApi專案的public目錄,注意使用左斜杠替換右斜杠、
修改后啟動Apache,則專案在localhost:80上啟動,如需修改埠請參考Apache組態檔的其他配置項,
更優雅的介面地址
默認的介面網址為類似于http://xxx.com/?s=App.User.Login(?s后為介面全限定名),不夠美觀,開啟URI路由匹配后可以實作http://xxx.com/User/Login的介面路徑,比較美觀,(App欄位可以省略)
開啟方式:
- 在
./config/sys.php修改enable_uri_match配置為true - 撰寫服務器Rewrite規則,若使用Nginx服務器,請直接參考官方檔案示例(http://docs.phalapi.net/#/v2.0/how-to-request?id=開啟uri路由匹配),
若使用Apache服務器:- 在
./public目錄下新建規則檔案.htaccess - 寫入下列內容(即將所有404請求轉發到index.php,作為一個controller)
RewriteEngine on RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ index.php - 重啟Apache服務器
- 在
PhalApi的ADM三層模型
有別于軟體開發領域常用的MVC三層模型,在后端純介面開發中,View層顯然沒有任何意義,所以PhalApi采用了創新的ADM三層模型,
- A - Api介面層,只負責接受請求、調度Domain層、發送回應
- D - Domain領域層,最關鍵,負責業務邏輯的處理
- M - Model資料層,只負責與資料庫的互動,注意,它不僅描述Object的基本資訊,還要實作一些會與資料庫互動的方法,類似于JavaEE中的Bean定義+DAO層

Api介面
三層模型所有的代碼均在./src/app目錄下,Api、Domain、Model目錄下默認生成了一些demo,可以洗掉,
在Api目錄下新建php類,假設為MyClass.php,注意下列要求:
namespace App\Api;- 命名空間,注意,必須限定到MyClass.php所在目錄,即如果MyClass.php放在./src/app/Api/Mobile下,則namespace App\Api\Mobile,use PhalApi\Api;- 要求使用Api類,class MyClass extends Api- 所有類都要繼承自Api類,
在類中定義的一系列public的函式,就是一個個實際的介面(注意,不是類是介面,而是類的成員函式是介面!所以這個類是起到了介面分類的作用)
介面的回傳格式永遠是JSON,形式為{ret, data, msg},其中ret是HTTP狀態碼,msg是錯誤提示資訊,而data就是我們的業務資料,在函式中return的關聯陣列會自動轉化成JSON,注入data,例如

下面介紹介面的呼叫網址,假設函式名為hello,類檔案為MyClass.php
| MyClass路徑 | 介面URL |
|---|---|
| ./src/app/Api/MyClass.php | XXX.com/MyClass/hello |
| ./src/app/Api/Mobile/MyClass.php | (正確)XXX.com/Mobile_MyClass/hello |
| ./src/app/Api/Mobile/MyClass.php | (錯誤)XXX.com/Mobile/MyClass/hello |
即若類檔案在Api目錄下發生了層疊,則需要加入下劃線分隔,而不是一直用斜杠,
下面介紹如何在Api層獲取和處理請求引數,
-
重寫
public function getRules()方法,public function getRules() { return array( '[FUNCTION NAME]' => array( '[PARAM NAME]' => array('name' => '...', 'require' => ..., 'type' => '...', 'source' => '...', 'desc' => '...', 'min' => ..., 'max' => ...) ); }回傳一個關聯陣列,鍵為該Api類下的函式名稱(即介面),值又是一個關聯陣列,鍵為引數名,值又是一個關聯陣列,用于進行該引數的配置,具體配置項可參考http://docs.phalapi.net/#/v2.0/api-params,下面介紹幾個常用的:
- name:string,前端請求時用的引數名
- require:boolean,是否必須
- type:引數型別,可以用string、int等
- source:string, 引數源,可以用post、get(注意小寫)等
- desc:引數說明,該說明會出現在自動檔案中
- min和max(均可選):當type是int時,可以起到后端引數校驗的作用
-
在介面對應函式的代碼中取引數:
$param_var = $this->[PARAM NAME]
取好引數,發給Domain層的對應函式,獲取回傳值,發送回應給服務器端,這就是Api層做的事,
一般來說,需要在頭部use一下App\Domain下的對應的Domain,然后在需要時new一個domain物件來使用,
Model模型
在Model目錄下新建php類,假設為User.php,通常的開發習慣是,資料庫一張表對應一個Model類,這樣可以實作對表的描述(類似于Mybatis與POJO的配合),以MySQL為例,注意下列要求:
namespace App\Model;- 同樣要嚴格限定到User.php目錄use PhalApi\Model\NotORMModel as NotORM;- 要求使用NotORM類,NotORM是PhalApi內部的封裝的MySQL互動引擎class User extends NotORM- 模型類必須繼承NotORM-
重寫protected function getTableName($id) { return 'user_score'; }protected function getTableName($id)方法(注意函式簽名帶參$id),回傳值是該模型對應的表名,
現在即可在User類下撰寫各個CURD功能的函式,函式引數是進行SQL查詢需要引數,具體使用請參考官方檔案http://docs.phalapi.net/#/v2.0/database-usage,整體風格是鏈式呼叫,例如:

首先要通過$this->getORM()獲取NotORM實體,然后組織相關SQL關鍵字即可,
值得一提的是,NotORM的功能非常的強大(起到了SQL陳述句Builder的作用,極大地避免了直接組織SQL陳述句),它甚至可以接收關聯陣列為引數進行各種智能的INSERT、UPDATE等操作,具體使用請參考http://docs.phalapi.net/#/v2.0/database-usage,靠這里的一兩句話是說不清道不明的,
如果有需要,NotORM也支持執行原生SQL陳述句,
Domain領域
在Domian領域下新建php類,假設為User.php,對于Domain類,要求比較簡單:
namespace App\Domain\;- 你懂的- 沒了,
Domain類不要求use框架內部的類,也不要求定義的類繼承相關類,
在User類下寫相關業務函式即可,一般來說,此處函式的引數是Api層請求需要的所有引數,
在業務函式中,呼叫Model層中封裝好的有關CURD函式,完成業務邏輯,一般來說,需要在User.php頭部use一下App\Model下的對應的User的model,在進行CURD操作時,new一個model物件來使用,
全域組態檔
在./config目錄下的app.php、dbs.php、di.php、sys.php就是四大全域組態檔,
如何在./src中腳本的任意位置取出其中配置的鍵值對?PhalApi用了依賴注入(DI)和反射的功能,實作了看起來非常Java的方式來獲取,
例如在app.php中配置了如下內容:
'token' => array( 'SALT' => 'imsalt', 'expire' => 7200)
要取鹽值,則取法為\PhalApi\DI()->config->get('app.token.SALT'),
即對于這四大組態檔,均用\PhalApi\DI()->config->get來訪問,引數為配置項的全限定名,
這四大組態檔的作用是:
- app.php - 用戶自定義的相關配置均追加于此
- dbs.php - 資料庫相關配置
- di.php - 依賴注入相關配置,當有新組件插入時需要修改
- sys.php - 系統級配置,例如是否除錯、URI匹配等
全域功能函式
如何定義一個在./src中任何位置都可以呼叫的功能函式?把這個函式的實作寫在./src/functions.php中即可,在需要呼叫時,使用\App\[FUNCTION NAME]來呼叫,
自動介面檔案
不同于Swagger的高侵入性,PhalApi的自動介面檔案系統非常的簡單優雅,不僅方便前端閱讀,還具備自解釋性,利于后續后端的維護,和JavaDoc類似,它全部依靠多行注釋完成,并且,多行注釋內允許使用基本的HTML標簽,如<b></b>來加粗等等,
注意,合法的多行注釋格式如下,首行有兩個星號,
/**
*
*/
這樣使用:
-
在Api層的每個類檔案的
use \PhalApi\Api;下行進行注釋,用于說明該類的整體作用 -
在getRules函式內進行的相關引數配置會自動反映到介面檔案中
-
在介面對應函式的正上方進行注釋,用于說明該介面的作用,語法如下:

- 第一行寫介面名稱
@desc后寫介面描述(description)@return后寫介面回傳值描述,@return [type] [name] [description]- 如果不想要該介面被自動檔案掃描,則添加
@ignore
若一切配置無誤,則可以在http://xxx.com/docs.php閱讀到自動生成的介面檔案,

介面檔案網頁還可以進行定制:
- 修改
./public/docs.php中的$projectName,可以修改左上角LOGO處的標題, - 如果需要公共說明(如圖中的統一說明),則在
./public/docs.php末尾添加php腳本閉標簽(?>)后,可以書寫HTML代碼,由于該頁面布局的原因,不建議將公共說明寫在頭部,
前端請求方式
- 對于PHP后端,前端在發送POST請求前必須設定如下請求頭,否則后端收不到資料:
header: {'content-type': "application/x-www-form-urlencoded; charset=UTF-8"}
? GET請求沒有類似限制,
-
前端用axios來POST時,data為Object,無需stringify
-
前端收到的回應作res.data后即為如下結構的Object:
{
"ret": 200,
"data": {
...
},
"msg": ""
}
? ret為http狀態碼,msg為錯誤提示資訊(當狀態碼非200時才有),data為業務資料
- 在自動介面檔案中,形如App.X_Y.Z的介面請求地址為
http://xxx.com/X_Y/Z(如果配置了URI匹配)
開發實體
我們以一個簡單的介面為例(獲取表中分數最高的n個記錄),展示一下PhalApi下一個介面的開發程序

-
這是一個公共介面,用于手機端,故在
./src/app/Api/Mobile下新建PHP類檔案Other.php -
進行namespace、use的基本配置,讓Other類繼承Api,撰寫類檔案注釋用于生成檔案,注意此處use...as...別名的使用,

-
重寫
getRules方法,接受一個引數n,函式名是getTopN

-
寫
getTopN函式以及相關檔案注釋,注意,介面函式都不需要引數,而是在內部獲取,

-
開始開發Domain層,在
./src/app/Domain/Mobile下新建PHP類檔案Other.php -
進行namespace的配置,寫業務邏輯代碼(當n>5時視為n=5處理),可以看到回傳的是一個回應體,所以在Api層是直接return的,注意此處同樣使用了別名
use \App\Model\Mobile\Other as ModelOther;
-
顯然該業務需要與資料庫互動,所以需要開發Model層,在
./src/app/Model/Mobile下新建PHP類檔案Other.php -
進行namespace和use配置,Other類繼承NotORM類,重寫
getTableName($id)方法 -
實作
getTopN($n)方法,注意,此處SQL查詢的結果會自動轉為關聯陣列傳到Domain層,Domain層再向上傳到Api層,Api層回應時關聯陣列就自動變成JSON結構注入到回應體的data中了,多么美妙!
-
至此,一個介面開發完成,相應的檔案也已經自動生成了,
系統日志
PhalApi提供了一個簡單日志系統,它將日志等級分類三級:error、info、debug,
保存目錄:./runtime/log
呼叫方式:\PhalApi\DI()->logger->error/info/debug([日志內容], [背景關系描述(可選)])
MySQL資料庫
MySQL資料庫需要在./config/dbs.php內配置,
PhalApi支持實作多庫集群、分庫分表,具體請參考:
- http://docs.phalapi.net/#/v2.0/database-connect
- http://docs.phalapi.net/#/v2.0/database-multi
- http://docs.phalapi.net/#/v2.0/database-other
服務端請求CUrl
如果有需要在服務器端利用服務器發送HTTP請求(例如小程式開發中的code2session),PhalApi為我們封裝了CUrl庫來實作,非常簡單,參考http://docs.phalapi.net/#/v2.0/curl,
快取體系
PhalApi支持許多種快取,

此處用常用的Redis說明,
- 在
./config/di.php中向$di注入Redis依賴:
$redis_config = array('host' => '127.0.0.1', 'port' => 6379);
$di->cache = new PhalApi\Cache\RedisCache($redis_config);
- 之后,在需要使用Redis的地方利用
\PhalApi\DI()->cache->set/get/delete等等即可
CORS跨域
利用跨域插件https://github.com/gongshunkai/phalapi-cors,配置相當簡單,
RESTful
由于PHP只是Apache/Nginx上的插件,HTTP服務是由它們提供的,所以若要實作嚴格的RESTful API,必須借助它們的支持,例如Apache,需要對.htaccess檔案進行配置,來轉發/重定向請求,將RESTful的請求轉化為傳統的,
具體可參考這個實踐:https://www.ctolib.com/luyuanxun-phalapi-restful.html
上線部署
PHP專案的部署非常簡單,上傳代碼就完事了!將整個phalapi目錄上傳到服務器上,然后確保你在遠端服務器上也進行了全文開頭的操作:
- Apache默認檔案路徑指向
./public - 配置好了Rewrite規則
此刻,你的介面就部署完成了,當然,你應該考慮一下:
- 真實上線,檔案不能讓別人隨意看到!請備份后洗掉
./public/docs.php - 洗掉無用的./sdk和./tests目錄
【全文終,謝謝您的閱讀!】
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/79324.html
標籤:PHP
上一篇:了解下Redis的SDS結構
