yii2-cookbook之定製response類型[翻譯]

以後會看心情不定時翻譯github上的yii-cookbook(url: https://github.com/samdark/yii2-cookbook/tree/master/book)
英文水平有限,有錯誤請一定指出來.

原文地址:https://github.com/samdark/yii2-cookbook/blob/master/book/response-formats.md

使用不同的response類型

現代的web和移動應用(對Server的要求)已經不僅僅滿足於渲染HTML了.現代的軟件架構已漸漸將UI看成是一個客戶端,客戶端負責直接和用戶發生交互,整個前端由服務端API驅動.(這種情況下)JSON和XML就常常作爲結構化數據的序列化和傳輸的載體在網絡上傳輸,所以創建這種response的能力已經成爲現代服務框架的必備要求.

response類型

你可能知道,yii2的action函數中需要(某種方法)”返回”結果,而不是直接echo:

// returning HTML result
return $this->render('index', [
    'items' => $items,
]);

有個好消息是yii2現在可以return其他格式的數據,如:

  • 數組
  • 實現了Arrayable接口的對象
  • 字符串
  • 實現了__toString()方法的對象

只是不要忘了在return前設置\Yii::$app->response->format來告訴YII你想要response的類型:

\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;

可選的類型有:

  • FORMAT_RAW
  • FORMAT_HTML
  • FORMAT_JSON
  • FORMAT_JSONP
  • FORMAT_XML

默認是FORMAT_HTML

JSON response

現在我們返回一個數組:

public function actionIndex()
{
    \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
    $items = ['some', 'array', 'of', 'data' => ['associative', 'array']];
    return $items;
}

返回結果:

{
    "0": "some",
    "1": "array",
    "2": "of",
    "data": ["associative", "array"]
}

注: 如果沒有設置response類型你會收到一個exception

同樣地,我們還可以返回一個對象:

public function actionView($id)
{
    \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
    $user = \app\models\User::find($id);
    return $user;
}

這裏的$user是一個ActiveRecord對象,而ActiveRecord類已實現了Arrayable接口,所以它可以很輕易地被轉成json:

{
    "id": 1,
    "name": "John Doe",
    "email": "[email protected]"
}

我們甚至可以返回一個對象數組:

public function actionIndex()
{
    \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
    $users = \app\models\User::find()->all();
    return $users;
}

這裏的$users就是一個ActiveRecord對象數組,不過在底層yii是通過\yii\helpers\Json::encode()來傳輸和轉化數據的,所以返回的時候請小心確保數組中元素的類型:

[
    {
        "id": 1,
        "name": "John Doe",
        "email": "[email protected]"
    },
    {
        "id": 2,
        "name": "Jane Foo",
        "email": "[email protected]"
    },
    ...
]

XML response

只要把response的format改成FORMAT_XML, 那麼你就能得到XML類型的返回值:

public function actionIndex()
{
    \Yii::$app->response->format = \yii\web\Response::FORMAT_XML;
    $items = ['some', 'array', 'of', 'data' => ['associative', 'array']];
    return $items;
}

//返回
<response>
    <item>some</item>
    <item>array</item>
    <item>of</item>
    <data>
        <item>associative</item>
        <item>array</item>
    </data>
</response>

是的,我們同樣可以把對象轉成XML:

public function actionIndex()
{
    \Yii::$app->response->format = \yii\web\Response::FORMAT_XML;
    $users = \app\models\User::find()->all();
    return $users;
}

//返回
<response>
    <User>
        <id>1</id>
        <name>John Doe</name>
        <email>[email protected]</email>
    </User>
    <User>
        <id>2</id>
        <name>Jane Foo</name>
        <email>[email protected]</email>
    </User>
</response>

定製化自己的response類型

讓我們搞一個自己的response類型玩玩吧.爲了讓例子有趣點,我們打算respond一個PHP數組格式的數據.

首先,我們需要先定製一個formatter. 創建文件components/PhpArrayFormatter.php:

<?php
namespace app\components;

use yii\helpers\VarDumper;
use yii\web\ResponseFormatterInterface;

class PhpArrayFormatter implements ResponseFormatterInterface
{
    public function format($response)
    {
        $response->getHeaders()->set('Content-Type', 'text/php; charset=UTF-8');
        if ($response->data !== null) {
            $response->content = "<?php\nreturn " . VarDumper::export($response->data) . ";\n";
        }
    }
}

現在我們需要在配置文件中註冊這個formatter:

return [
    // ...
    'components' => [
        // ...
        'response' => [
            'formatters' => [
                'php' => 'app\components\PhpArrayFormatter',
            ],
        ],
    ],
];

好了,萬事俱備, 現在在controller裏創建一個action:

public function actionTest()
{
    Yii::$app->response->format = 'php';
    return [
        'hello' => 'world!',
    ];
}

執行之後的response是這樣的:

<?php
return [
    'hello' => 'world!',
];
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章