在進(jìn)行API開發(fā)的時候,需要事先定義好app與server交互的數(shù)據(jù)格式,這樣前端人員與服務(wù)端人員才能夠事先決定好如何獲取數(shù)據(jù)、如何解析數(shù)據(jù)、如何傳輸協(xié)議。
在我看來目前接口協(xié)議無外乎這三種情況:
1. json數(shù)據(jù)進(jìn)行交互
2. xml數(shù)據(jù)進(jìn)行交互
3. 自定義數(shù)據(jù)格式交互
自定義數(shù)據(jù)格式進(jìn)行前后端的數(shù)據(jù)交互,需要花費(fèi)較大的精力,而且需要很有經(jīng)驗(yàn)的人設(shè)計的協(xié)議才會確保各個平臺的兼容以及良好的可閱讀性。并且解析、封裝都需要自己來用代碼實(shí)現(xiàn),很多第三方庫都沒辦法用上。因?yàn)檫@里我不進(jìn)行討論。主要說說json與xml作為交互數(shù)據(jù)。
我在我的response中封裝了json與xml??蛻舳丝梢愿鶕?jù)自己的需要進(jìn)行選擇是獲取json數(shù)據(jù)還是xml。指定方法是在請求的url中指定format=json/xml。這里為了程序的健壯,我會默認(rèn)指定一種數(shù)據(jù)格式的返回,也就是如果客戶端沒有或者忘記設(shè)置format時,默認(rèn)返回json數(shù)據(jù)。
json數(shù)據(jù)的封裝,在php中用json來進(jìn)行數(shù)據(jù)交互是非常方便。實(shí)現(xiàn)代碼:
private static function jsonSucEncode($code, $msg, $datas){
if(!is_numeric($code)){
return '';
}
$ret = array(
'succode' => $code,
'sucmsg' => $msg,
'datas' => $datas,
);
echo json_encode($ret);
}
code表示返回的狀態(tài)碼,這個狀態(tài)碼應(yīng)該在文檔中進(jìn)行說明含義,并事先定義好msg表示返回的信息,我覺得這個字段是有必要的,至少方便客戶端開發(fā)人員進(jìn)行錯誤定位。備注:我最開始就沒有設(shè)計這個字段,而只是設(shè)計了code這個狀態(tài)嗎,前端人員每次都要到文檔中進(jìn)行查看這個狀態(tài)碼是什么含義,很影響開發(fā)速度。datas:這個就是返回給前端的業(yè)務(wù)數(shù)據(jù)了。
然后使用json_encode()對這個數(shù)據(jù)編碼后,就是json數(shù)據(jù)了。
xml數(shù)據(jù)的封裝相對來說比較麻煩,方法有很多,我使用的是用字符串進(jìn)行拼接:
private static function xmlSucEncode($code, $msg, $datas){
if(!is_numeric($code)){
return '';
}
$ret = array(
'succode' => $code,
'sucmsg' => $msg,
'datas' => $datas,
);
echo self::xml($ret);
}
private static function xml($datas){
header("Content-Type:text/xml");
$xml = "<?xml version='1.0' encoding='UTF-8'?>";
$xml .= '<root>';
$xml .= self::createXML($datas);
$xml .= '</root>';
return $xml;
}
private static function createXML($datas){
$xml = $attr = "";
foreach ($datas as $k=>$v){
if(is_numeric($k)) {// 如果k是數(shù)字,則將其作為一個屬性來使用
$attr = " id='{$k}'";
$k = "item";
}
$xml .= "<{$k}{$attr}>";
$xml .= is_array($v) ? self::createXML($v) : $v;
$xml .="</{$k}>";
}
return $xml;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
然后現(xiàn)在xml數(shù)據(jù)、json數(shù)據(jù)的封裝方式都有了,此時應(yīng)該提供一個統(tǒng)一的接口,供前臺來調(diào)用,通過參數(shù)進(jìn)行控制,返回xml數(shù)據(jù)還是json數(shù)據(jù)。而不是這樣子拋出去兩個接口,讓客戶端的人自己選擇。同時拋出去兩個接口還有一個問題:如果要更換,更換的就是接口的名稱以及它的參數(shù)。
這里我定義的統(tǒng)一接口:
public static function sendEncode($code, $msg, $state, $datas=array(), $type=self::JSON){
// 如果請求參數(shù)設(shè)置了請求類型,則返回請求的類型,否則使用參數(shù)中的類型,默認(rèn)為json
$type = isset($_GET['format']) ? $_GET['format'] : $type;
switch ($type){
// json格式數(shù)據(jù)
case self::JSON :
if($state == self::SUCCESS){
self::jsonSucEncode($code, $msg, $datas);
}else{
self::jsonErrEncode($code, $msg);
}
exit;
break;
// xml數(shù)據(jù)
case self::XML :
if($state == self::SUCCESS){
self::xmlSucEncode($code, $msg, $datas);
}else{
self::xmlErrEncode($code, $msg);
}
exit;
break;
// 其他數(shù)據(jù)格式請求
default:
self::jsonErrEncode(self::ILLEGAL_CODE, self::ILLEGAL_MSG);
exit;
break;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
|