如何修改响应格式本身?

How can I modify the response formatting itself?

在行动中我需要回应一些 XML。我为此使用 Response::FORMAT_XML,效果很好。

// In a controller:

public static function actionFetchData() {
    Yii::$app->response->format = Response::FORMAT_XML;

    return [
        'a' => 'b',
        ['c', 'd'],
        'e' => ['f', 'g']
    ];
}

浏览器中的结果:

<?xml version="1.0" encoding="UTF-8"?>
<response>
  <a>b</a>
  <item>
    <item>c</item>
    <item>d</item>
  </item>
  <e>
    <item>f</item>
    <item>g</item>
  </e>
</response>

但是,我想将根标签名称从 response 更改为 data。这应该是可能的,因为用于呈现 XML 的 XmlResponseFormatter 具有 属性 rootTag。我怎样才能做到这一点?

或者一般来说:如何更改格式化程序的设置(还有 JSON 或其他)?

一种方法是为 XML 创建自己的格式化程序对象。原因:在 Yii::$app->response 中,操作中不存在格式问题 - 它将在稍后创建,当响应被呈现时,修改它为时已晚。但是我们可以创建一个新的格式化程序并将其设置为 XML 的格式化程序。这是一个有效的选项。

public static function actionMetaInfo($docId) {
    $formatter = new XmlResponseFormatter([
        'rootTag' => 'data',
        'itemTag' => 'unnamed',
    ]);
    Yii::$app->response->formatters[Response::FORMAT_XML] = $formatter;
    Yii::$app->response->format = Response::FORMAT_XML;

    return [
        'a' => 'b',
        ['c', 'd'],
        'e' => ['f', 'g']
    ];
}

现在输出:

<?xml version="1.0" encoding="UTF-8"?>
<data>
    <a>b</a>
    <unnamed>
        <unnamed>c</unnamed>
        <unnamed>d</unnamed>
    </unnamed>
    <e>
        <unnamed>f</unnamed>
        <unnamed>g</unnamed>
    </e>
</data>

这里我也更改了itemTag。这样,我们还可以修改其他 Formatter 的属性(例如 JsonResponseFormatter)。

如果您想为所有应用程序修改 XML 响应格式化程序,只需将其添加到您的配置文件中即可:

'components' => [
    'response' => [
        'formatters' => [
            'xml' => [
                'class' => 'yii\web\XmlResponseFormatter',
                'rootTag' => 'data',
            ],
        ],
    ],
],

如果您想更改特定于特定操作的格式,请使用 :.

 Yii::$app->response->format = Response::FORMAT_XML;
 Yii::$app->response->formatters = [
        'xml' => [
            'class' => 'yii\web\XmlResponseFormatter',
            'rootTag' => 'data',
        ],
    ];

    return [
        'a' => 'b',
        ['c', 'd'],
        'e' => ['f', 'g']
    ];