Yii2模块自定义响应类

Jep*_*epi 6 php yii2

我已经定义了一个自定义响应类,并试图在模块中使用它.

在控制器操作中,我返回一个结果数组,但不使用自定义响应类.

相反,使用的类是默认的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',
            ],
        ],
    ],
Run Code Online (Sandbox Code Playgroud)

在控制器中我编辑了行为方法:

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;
}
Run Code Online (Sandbox Code Playgroud)

在行动中,如果我这样做:

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;
}
Run Code Online (Sandbox Code Playgroud)

我得到了这个结果(正如yii\web\Response所预期的那样):

[
{
    "id": 1,
    "name": "John",
    "surname": "Davis"
},
{
    "id": 2,
    "name": "Marie",
    "surname": "Baker"
},
{
    "id": 3,
    "name": "Albert",
    "surname": "Bale"
}
]
Run Code Online (Sandbox Code Playgroud)

但如果我将动作更改为:

$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;
Run Code Online (Sandbox Code Playgroud)

然后我得到预期的结果,这是:

{
"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"
    }
]}
Run Code Online (Sandbox Code Playgroud)

似乎我定义的行为没有做任何事情.

在动作中返回数组并使用自定义响应组件需要做什么?

提前致谢

oak*_*max 4

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',
            ],
        ]
    ]);
}
Run Code Online (Sandbox Code Playgroud)

但我认为在模块中完全替换父应用程序的响应组件是一个坏主意。更好的方法是根据您的需要修改响应行为。例如,您可以使用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
        ];
    });
}
Run Code Online (Sandbox Code Playgroud)