Custom Yii2 Answer Class

I defined a custom response class and tried to use it in a module.

In the controller action, I return an array of results, but the custom response class is not used.

Instead, the default yii \ web \ Response is used.

My implementation

Module configuration in 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', ], ], ], 

In the controller, I edited the behavior method:

 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; } 

In action, if I do:

 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; } 

I get this result (as expected from yii \ web \ Response):

 [ { "id": 1, "name": "John", "surname": "Davis" }, { "id": 2, "name": "Marie", "surname": "Baker" }, { "id": 3, "name": "Albert", "surname": "Bale" } ] 

But if I changed the action to this:

 $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; 

Then I get the expected result, which is as follows:

 { "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" } ]} 

It seems that the behavior that I defined does nothing.

What do I need to do to just get the array back into action and use the custom response component?

Thank you in advance

+5
source share
1 answer

yii\base\Module does not have a response component, so your configuration will not work. Instead of adding a response component to your module You can change Yii::$app->response inside MyMod::init() .

If you want to completely replace Yii::$app->response with your own component:

 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', ], ] ]); } 

But I think it is a bad idea to completely replace the Response component of the parent application in the module. The best way is to change the response behavior for your needs. For example, you can use EVENT_BEFORE_SEND and create your own data structure in response:

 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 ]; }); } 
+3
source

All Articles