我已定义了一个自定义响应类,并尝试在模块中使用它。
在控制器操作中,我返回一个结果数组,但不使用自定义响应类。
相反,使用的类是默认的yii \ web \ Response
我的实施
config / web.php中的模块配置:
'mymodule' => [
'class' => 'app\modules\mymod\Mymod',
'components' => [
'response' => [
'class' => 'app\modules\mymod\components\apiResponse\ApiResponse',
'format' => yii\web\Response::FORMAT_JSON,
'charset' => 'UTF-8',
],
],
],
在控制器中我编辑了行为方法:
public function behaviors() {
$behaviors = parent::behaviors();
$behaviors['contentNegotiator'] = [
'class' => 'yii\filters\ContentNegotiator',
'response' => $this->module->get('response'),
'formats' => [ //supported formats
'application/json' => \yii\web\Response::FORMAT_JSON,
],
];
return $behaviors;
}
如果我采取行动:
public function actionIndex() {
\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
$dataList = [
['id' => 1, 'name' => 'John', 'surname' => 'Davis'],
['id' => 2, 'name' => 'Marie', 'surname' => 'Baker'],
['id' => 3, 'name' => 'Albert', 'surname' => 'Bale'],
];
return $dataList;
}
我得到了这个结果(正如yii \ web \ Response所预期的那样):
[
{
"id": 1,
"name": "John",
"surname": "Davis"
},
{
"id": 2,
"name": "Marie",
"surname": "Baker"
},
{
"id": 3,
"name": "Albert",
"surname": "Bale"
}
]
但如果我将动作更改为:
$dataList = [
['id' => 1, 'name' => 'John', 'surname' => 'Davis'],
['id' => 2, 'name' => 'Marie', 'surname' => 'Baker'],
['id' => 3, 'name' => 'Albert', 'surname' => 'Bale'],
];
//return $dataList;
$resp = $this->module->get('response'); //getting the response component from the module configuration
$resp->data = $dataList;
return $resp;
然后我得到了预期的结果,即:
{
"status": {
"response_code": 0,
"response_message": "OK",
"response_extra": null
},
"data": [
{
"id": 1,
"name": "John",
"surname": "Davis"
},
{
"id": 2,
"name": "Marie",
"surname": "Baker"
},
{
"id": 3,
"name": "Albert",
"surname": "Bale"
}
]}
我所定义的行为似乎没有做任何事情。
我需要做什么才能在操作中返回数组并使用自定义响应组件?
提前致谢
答案 0 :(得分:3)
yii\base\Module
没有响应组件,因此您的配置无效。
而不是将response
组件添加到您的模块中您可以更改Yii::$app->response
函数内的MyMod::init()
。
如果您想完全用您自己的组件替换Yii::$app->response
:
public function init()
{
parent::init();
\Yii::configure(\Yii::$app, [
'components' => [
'response' => [
'class' => 'app\modules\mymod\components\apiResponse\ApiResponse',
'format' => yii\web\Response::FORMAT_JSON,
'charset' => 'UTF-8',
],
]
]);
}
但我认为在模块中完全替换父应用程序的Response组件是一个坏主意。更好的方法是修改满足您需求的响应行为。例如,您可以使用EVENT_BEFORE_SEND
并在响应中构建自己的数据结构:
public function init()
{
parent::init();
// you can use ContentNegotiator at the level of module
// and remove this behavior declaration from controllers
\Yii::configure($this, [
'as contentNegotiator' => [
'class' => 'yii\filters\ContentNegotiator',
// if in a module, use the following IDs for user actions
// 'only' => ['user/view', 'user/index']
'formats' => [
'application/json' => Response::FORMAT_JSON,
],
],
]);
// you can daclare handler as function in you module and pass it as parameter here
\Yii::$app->response->on(Response::EVENT_BEFORE_SEND, function ($event) {
$response = $event->sender;
// here you can get and modify everything in current response
// (data, headers, http status etc.)
$response->data = [
'status' => 'Okay',
'data' => $response->data
];
});
}