iT邦幫忙

0

php return code 的api設計

我的 response json 結構是

{
    "code": 0,
    "message": "",
    "data": ""
}

有成功的話資料都會在 data
我在 index.php 的預設值為

$return['code'] = 0;
$return['message'] = '';
$return['data'] = '';

只是現在有個問題
假設 router 為 /signin

$return['data'] = (new User())->SIGNIN();
return $return;

我丟給 class User
假設在 SIGNIN 資料庫邏輯中找不到此帳號則回傳 code = 400, message = '無此帳號' 這兩種資訊給使用者
User Class

$res = DB::queryFirstRow(
            "SELECT * FROM `user` WHERE `email` = %s AND `password` = %s",
            $body['email'], $body['password']
        );

        if (!$res) {
            $return['code'] = 400;
            $return['message'] = '無此帳號';
        }

那我該如何在 User 中得知有錯誤時,指定第一層的 code, message 而不是變成這樣

{
    "code": 0,
    "message": "",
    "data": {
        "code": 400,
        "message": "無此帳號"
    }
}

畢竟我一開始就指定了在 $return['data'] 做資料庫邏輯....所以出現以上的狀況

改成 $return 我就可以在 User 做 $return['code'], $return['message'] 指定,但這樣會有嚴重重複的問題,而且不會只有這個 class...
我在 index.php 做了預設就是除非是特殊狀況,用意我就不說明了

這種情況能怎麼改善呢?!

有想到一個方式是在 router 判斷 data 吐回來的狀況,但這樣就有點多此一舉...想說讓 router 乾淨點
否則 model跟router都要判斷就有點呵呵

1
Han
iT邦新手 4 級 ‧ 2019-12-16 16:04:23
最佳解答
$result = (new User())->SIGNIN($body) ;

if ($result['code'] !== 400)
{
    $return = $result ;
}
else
{
    $return['data'] = $result ;
}

return $return;

根據回傳class的User回傳的結果去決定要不要把資料放進$return['data']

不知道你要的效果是不是這樣??

========更新=========
有想到一個方式是在 router 判斷 data 吐回來的狀況,但這樣就有點多此一舉...想說讓 router 乾淨點
抱歉,沒看到這句/images/emoticon/emoticon06.gif

看更多先前的回應...收起先前的回應...
Han iT邦新手 4 級 ‧ 2019-12-16 16:07:09 檢舉

不然應該就是要把return丟進去進行覆蓋,並且回傳整份return回來到router,再覆蓋router內的return,但這樣設計有點..怪

松松 iT邦研究生 2 級 ‧ 2019-12-16 16:14:36 檢舉

我甚至有個做法是用

public function __construct()

先指定

$this->return = [
        'code' => 0,
        'message' => '',
        'data' => '',
    ];

但等於是每個 class 都會有一樣的 就有點呵呵

Han iT邦新手 4 級 ‧ 2019-12-16 16:22:32 檢舉

我通常會將這種情形在最外面的function使用try catch,catch中回應另一份response

所以把(new User())->SIGNIN($body)中的

if(!res)
{
    throw new Exception('....')
}

router寫try catch進行例外處理,不知道這樣你能接受嗎XD

松松 iT邦研究生 2 級 ‧ 2019-12-16 16:25:33 檢舉

我是有想過把

$this->return = [
        'code' => 0,
        'message' => '',
        'data' => '',
    ];

提出來到一個 class
然後底下需要用到的在 $this->return = Class::function();
然後使用...

松松 iT邦研究生 2 級 ‧ 2019-12-16 17:26:07 檢舉

確實 try catch 好像是一個解

try {
        $return['data'] = (new User())->SIGNIN();
    } catch (Exception $e) {
        $return['code'] = 400;
        $return['message'] = $e->getMessage();
    }
Han iT邦新手 4 級 ‧ 2019-12-16 17:33:48 檢舉

router內使用try catch應該不會不乾淨
日後User SIGNIN設計想多點錯誤過濾也非常好中斷
各種拋錯,router catch即可

松松 iT邦研究生 2 級 ‧ 2019-12-16 17:36:05 檢舉

好像比在 model + router 都判斷好多了點

1
舜~
iT邦高手 1 級 ‧ 2019-12-16 16:05:09

array_merge($defaultValue , (new User())->SIGNIN($body));

這樣呢? 借用array_merge相同key後面覆蓋前面的特性

松松 iT邦研究生 2 級 ‧ 2019-12-16 16:12:34 檢舉

我在 router 用了你說的 array_merge 方式
我在 User return 假設登入成功

$return['token'] = 'eifjiwjg';
return $return;

它的結構會變成

{
    "code": 0,
    "message": "",
    "data": {
        "token": "eifjiwjg"
    },
    "token": "eifjiwjg"
}
1
淺水員
iT邦研究生 4 級 ‧ 2019-12-16 16:24:24

我不會讓 User 物件去管 http 要回傳什麼 JSON
如果找不到使用者,可能會回傳 flase 或是 null
對於 http 要回傳什麼東西是由 route 或是 controller 去負責

松松 iT邦研究生 2 級 ‧ 2019-12-16 16:26:54 檢舉

了解
所以決定權還是會回到 router 上
等於是 User 判斷一次,router 又要再判斷一次並 return,我一開始也是這樣想的
我是想說假設 User 有五種錯誤, router 就會有五個判斷....

淺水員 iT邦研究生 4 級 ‧ 2019-12-16 16:30:28 檢舉

考慮到 User 可以在不同的專案中重複使用(其他專案可能要回應不同的資料),我是覺得這樣比較好,分工也比較明確。

淺水員 iT邦研究生 4 級 ‧ 2019-12-16 16:44:37 檢舉

如果狀況比較多種,可以考慮設一些 const
例如: User::ERROR_NOT_FOUND

此外,有些每次請求都要跑的驗證可以考慮在 middleware 處理
這樣就不會每個 controller 一堆重複的程式碼

1
eric19740521
iT邦新手 4 級 ‧ 2019-12-22 05:42:51

我給你看我的程式碼吧!!!

傳回 json /xml/字串
見仁見智...

我習慣傳回json....
前後端都統一,一個模式在處理api訊息


$lc_where = "";

if ($key <> "") {
	$lc_where = " where com_id = '$key' or com_name like '%$key%' "; 
}
	
$lc_sqlcommand="select * from company $lc_where order by  com_id ";

$result = mysql_query( $lc_sqlcommand);
if ( !$result ) {

	$response = array(); 			//json output參數初始值
	$response["success"] = 0; 		//成功取得資料,就給1
	$response["message"] = "company資料讀取失敗"; 		
	echo json_encode($response, JSON_UNESCAPED_UNICODE);
	
	return;
}

//json字串整理
$response = array(); 			//json output參數初始值
$response["udata"] = array(); 	//json data資料列
while($row = mysql_fetch_assoc($result)) {
	$row_array['com_id'] = trim($row['com_id']);
	$row_array['com_name'] = trim($row['com_name']);
	$row_array['com_tel'] = trim($row['com_tel']);

    array_push($response["udata"],$row_array);
}

//json字串整理
//$response = array(); 			//json output參數初始值
$response["rows"] = mysql_affected_rows(); 
$response["success"] = 1; 		//成功取得資料,就給1
$response["message"] = "成功取回"; 
echo json_encode($response, JSON_UNESCAPED_UNICODE);

我要發表回答

立即登入回答