對于接口響應(yīng),PhalApi默認(rèn)使用了HTTP+JSON。通過HTTP/HTTPS協(xié)議進行通訊,返回的結(jié)果則使用JSON格式進行傳遞。正常情況下,當(dāng)接口服務(wù)正常響應(yīng)時,如前面的Hello World接口,可能看到以下這樣的響應(yīng)頭部信息和返回內(nèi)容。
HTTP/1.1 200 OK
Content-Type: application/json;charset=utf-8
... ...
{"ret":200,"data":{"title":"Hello World!"},"msg":""}
而當(dāng)接口項目拋出了未捕捉的異常,或者因PHP語法問題而出現(xiàn)Error時,則沒有內(nèi)容返回,并且得到一個500的響應(yīng)狀態(tài)碼。類似如下:
HTTP/1.1 500 Internal Server Error
回顧一下默認(rèn)接口服務(wù)返回的內(nèi)容。類似如下:
{
"ret": 200,
"data": {
"title": "Hello World!",
"content": "PHPer您好,歡迎使用PhalApi!",
"version": "2.0.0",
"time": 1499477583
},
"msg": ""
}
ret字段是返回狀態(tài)碼,200表示成功;data字段是項目提供的業(yè)務(wù)數(shù)據(jù),由接口開發(fā)人員定義;msg是異常情況下的錯誤提示信息。下面分別說之。
業(yè)務(wù)數(shù)據(jù)data為接口和客戶端主要溝通對接的數(shù)據(jù)部分,可以為任何類型,由接口開發(fā)人員定義定義。但為了更好地擴展、向后兼容,建議都使用可擴展的集合形式,而非原生類型。也就是說,應(yīng)該返回一個數(shù)組,而不應(yīng)返回整型、布爾值、字符串這些基本類型。
業(yè)務(wù)數(shù)據(jù)主要是在Api層返回,即對應(yīng)接口類的方法的返回結(jié)果。如下面的默認(rèn)接口服務(wù)?s=Site.Index
的實現(xiàn)代碼。
<?php
namespace App\Api;
use PhalApi\Api;
class Site extends Api {
public function index() {
return array(
'title' => 'Hello World!',
'content' => \PhalApi\T('Hi {name}, welcome to use PhalApi!', array('name' => $this->username)),
'version' => PHALAPI_VERSION,
'time' => $_SERVER['REQUEST_TIME'],
);
}
實際上,具體的業(yè)務(wù)數(shù)據(jù)需要一段復(fù)雜的處理,以滿足特定業(yè)務(wù)場景下的需要。Api層需要與Domain層和Model層共同協(xié)作,完成指定的功能。這里暫且知道接口結(jié)果是在Api層返回,對應(yīng)接口類成員方法返回的結(jié)果即可。
返回狀態(tài)碼ret,用于表示接口響應(yīng)的情況。參照自HTTP的狀態(tài)碼,ret主要分為四大類:正常響應(yīng)、重定向、非法請求、服務(wù)器錯誤。
分類 | ret范圍 | 基數(shù) | 說明 |
---|---|---|---|
正常響應(yīng) | 200~299 | 200 | 表示接口服務(wù)正常響應(yīng) |
重定向 | 300~399 | 300 | 表示重定向,對應(yīng)異常類RedirectException的異常碼 |
非法請求 | 400~499 | 400 | 表示客戶端請求非法,對應(yīng)異常類BadRequestException的異常碼 |
服務(wù)器錯誤 | 500~599 | 500 | 表示服務(wù)器內(nèi)容錯誤,對應(yīng)異常類InternalServerErrorException的異常碼 |
正常響應(yīng)時,通常返回ret = 200,并且同時返回data部分的業(yè)務(wù)數(shù)據(jù),以便客戶端能實現(xiàn)所需要的業(yè)務(wù)功能。
值得注意的是,拋出的異常應(yīng)該繼承于PhalApi\Exception類,并且構(gòu)造函數(shù)的第一個參數(shù),是返回給客戶端的錯誤提示信息,對應(yīng)下面將講到的msg字段。第二個參數(shù)是返回狀態(tài)碼的疊加值,也就是說最終的ret狀態(tài)碼都會在400的基數(shù)上加上這個疊加值,即:401 = 400 + 1。
例如,常見地,當(dāng)簽名失敗時可以返回一個401錯誤,并提示“簽名失敗”。
<?php
namespace App\Api;
use PhalApi\Api;
use PhalApi\Exception\BadRequestException;
class Hello extends Api {
public function fail() {
throw new BadRequestException('簽名失敗', 1);
}
}
會得到以下結(jié)果輸出:
{
"ret": 401,
"data": [],
"msg": "Bad Request: 簽名失敗"
}
當(dāng)接口不是正常響應(yīng),即ret不在2XX系列內(nèi)時,msg字段會返回相應(yīng)的錯誤提示信息。即當(dāng)有異常觸發(fā)時,會自動將異常的錯誤信息作為錯誤信息msg返回。
除了使用JSON格式返回外,還可以使用其他格式返回結(jié)果。
例如在部分H5混合應(yīng)用頁面進行異步請求的情況下,客戶端需要服務(wù)端返回JSONP格式的結(jié)果,則可以這樣在DI配置文件./config/di.php中去掉以下注釋。
// 支持JsonP的返回
if (!empty($_GET['callback'])) {
$di->response = new \PhalApi\Response\JsonpResponse($_GET['callback']);
}
目前,PhalApi 2.x 已經(jīng)支持的響應(yīng)格式有:
響應(yīng)格式 | 實現(xiàn)類 |
---|---|
JSON格式 | PhalApi\Response\JsonResponse |
JSONP格式 | PhalApi\Response\JsonResponse |
XML格式 | PhalApi\Response\JsonResponse |
控制臺格式 | PhalApi\Response\JsonResponse |
當(dāng)需要返回一種當(dāng)前PhalApi沒提供的格式,需要返回其他格式時,可以:
\PhalApi\DI()->response
服務(wù)開啟調(diào)試模式很簡單,主要有兩種方式:
&__debug__=1
全部請求開啟調(diào)試:把配置文件./Config/sys.php
文件中的配置改成'debug' => true,
正常響應(yīng)的情況下,當(dāng)開啟調(diào)試模式后,會返回多一個debug
字段,里面有相關(guān)的調(diào)試信息。如下所示:
{
"ret": 200,
"data": {
},
"msg": "",
"debug": {
"stack": [ // 自定義埋點信息
],
"sqls": [ // 全部執(zhí)行的SQL語句
]
}
}
溫馨提示:調(diào)試信息僅當(dāng)在開啟調(diào)試模式后,才會返回并顯示。
在發(fā)生未能捕捉的異常時,并且開啟調(diào)試模式后,會將發(fā)生的異常轉(zhuǎn)換為對應(yīng)的結(jié)果按結(jié)果格式返回,即其結(jié)構(gòu)會變成以下這樣:
{
"ret": 0, // 異常時的錯誤碼
"data": [],
"msg": "", // 異常時的錯誤信息
"debug": {
"exception": [ // 異常時的詳細堆棧信息
],
"stack": [ // 自定義埋點信息
],
"sqls": [ // 全部執(zhí)行的SQL語句
]
}
}
查看全部執(zhí)行的SQL語句
debug.sqls中會顯示所執(zhí)行的全部SQL語句,由框架自動搜集并統(tǒng)計。最后顯示的信息格式是:
[序號 - 當(dāng)前SQL的執(zhí)行時間ms]所執(zhí)行的SQL語句及參數(shù)列表
示例:
[1 - 0.32ms]SELECT * FROM tbl_user WHERE (id = ?); -- 1
表示是第一條執(zhí)行的SQL語句,消耗了0.32毫秒,SQL語句是SELECT * FROM tbl_user WHERE (id = ?);
,其中參數(shù)是1。
查看自定義埋點信息
debug.stack中埋點信息的格式如下:
[#序號 - 距離最初節(jié)點的執(zhí)行時間ms - 節(jié)點標(biāo)識]代碼文件路徑(文件行號)
示例:
[#0 - 0ms]/path/to/phalapi/public/index.php(6)
表示,這是第一個埋點(由框架自行添加),執(zhí)行時間為0毫秒,所在位置是文件/path/to/phalapi/public/index.php
的第6行。即第一條的埋點發(fā)生在框架初始化時。
與SQL語句的調(diào)試信息不同的是,自定義埋點則需要開發(fā)人員根據(jù)需要自行紀(jì)錄,可以使用全球追蹤器PhalApi\DI()->tracer
進行紀(jì)錄,其使用如下:
// 添加紀(jì)錄埋點
PhalApi\DI()->tracer->mark();
// 添加紀(jì)錄埋點,并指定節(jié)點標(biāo)識
PhalApi\DI()->tracer->mark('DO_SOMETHING');
通過上面方法,可以對執(zhí)行經(jīng)過的路徑作標(biāo)記。你可以指定節(jié)點標(biāo)識,也可以不指定。對一些復(fù)雜的接口,可以在業(yè)務(wù)代碼中添加這樣的埋點,追蹤接口的響應(yīng)時間,以便進一步優(yōu)化性能。當(dāng)然,更專業(yè)的性能分析工具推薦使用XHprof。
參考:用于性能分析的XHprof擴展類庫。
當(dāng)有未能捕捉的接口異常時,開啟調(diào)試模式后,框架會把對應(yīng)的異常轉(zhuǎn)換成對應(yīng)的返回結(jié)果,并在debug.exception中體現(xiàn)。而不是像正常情況直接500,頁面空白。這些都是由框架自動處理的。
例如,讓我們故意制造一些麻煩,手動拋出一個異常。
class Hello extends Api {
public function fail() {
throw new Exception('這是一個演示異常調(diào)試的示例', 501);
}
}
再次請求后,除了SQL語句和自定義埋點信息外,還會看到這樣的異常堆棧信息。然后便可根據(jù)返回的異常信息進行排查定位問題。
當(dāng)需要添加其他調(diào)試信息時,可以使用PhalApi\DI()->response->setDebug()
進行添加。
如:
class Hello extends Api {
public function fail() {
$x = 'this is x';
$y = array('this is y');
\PhalApi\DI()->response->setDebug('x', $x);
\PhalApi\DI()->response->setDebug('y', $y);
}
}
請求后,可以看到:
"debug": {
"x": "this is x",
"y": [
"this is y"
]
}
更多建議: