牛骨文教育服务平台(让学习变的简单)
博文笔记

yii2-cookbook之定制response类型[翻译]

创建时间:2015-10-16 投稿人: 浏览次数:511

以后会看心情不定时翻译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 = yiiwebResponse::FORMAT_JSON;

可选的类型有:

  • FORMAT_RAW
  • FORMAT_HTML
  • FORMAT_JSON
  • FORMAT_JSONP
  • FORMAT_XML

默认是FORMAT_HTML

JSON response

现在我们返回一个数组:

public function actionIndex()
{
    Yii::$app->response->format = yiiwebResponse::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 = yiiwebResponse::FORMAT_JSON;
    $user = appmodelsUser::find($id);
    return $user;
}

这里的$user是一个ActiveRecord对象,而ActiveRecord类已实现了Arrayable接口,所以它可以很轻易地被转成json:

{
    "id": 1,
    "name": "John Doe",
    "email": "john@example.com"
}

我们甚至可以返回一个对象数组:

public function actionIndex()
{
    Yii::$app->response->format = yiiwebResponse::FORMAT_JSON;
    $users = appmodelsUser::find()->all();
    return $users;
}

这里的$users就是一个ActiveRecord对象数组,不过在底层yii是通过yiihelpersJson::encode()来传输和转化数据的,所以返回的时候请小心确保数组中元素的类型:

[
    {
        "id": 1,
        "name": "John Doe",
        "email": "john@example.com"
    },
    {
        "id": 2,
        "name": "Jane Foo",
        "email": "jane@example.com"
    },
    ...
]

XML response

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

public function actionIndex()
{
    Yii::$app->response->format = yiiwebResponse::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 = yiiwebResponse::FORMAT_XML;
    $users = appmodelsUser::find()->all();
    return $users;
}

//返回
<response>
    <User>
        <id>1</id>
        <name>John Doe</name>
        <email>john@example.com</email>
    </User>
    <User>
        <id>2</id>
        <name>Jane Foo</name>
        <email>jane@example.com</email>
    </User>
</response>

定制化自己的response类型

让我们搞一个自己的response类型玩玩吧.为了让例子有趣点,我们打算respond一个PHP数组格式的数据.

首先,我们需要先定制一个formatter. 创建文件components/PhpArrayFormatter.php:

<?php
namespace appcomponents;

use yiihelpersVarDumper;
use yiiwebResponseFormatterInterface;

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
return " . VarDumper::export($response->data) . ";
";
        }
    }
}

现在我们需要在配置文件中注册这个formatter:

return [
    // ...
    "components" => [
        // ...
        "response" => [
            "formatters" => [
                "php" => "appcomponentsPhpArrayFormatter",
            ],
        ],
    ],
];

好了,万事俱备, 现在在controller里创建一个action:

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

执行之后的response是这样的:

<?php
return [
    "hello" => "world!",
];
声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。