4

我正在尝试为在 Yii 2.0.5 中创建的 Web 服务创建一个请求和响应记录器,用于调试目的。

基本上我的动机是跟踪所有的请求、请求数据、响应数据,为此我使用了 Yii 事件。到目前为止,我已经编写了这样的代码:

用户控制器

use yii\rest\ActiveController;
use yii\base\Event;
use yii\web\Response;

Event::on(ActiveController::className(), ActiveController::EVENT_AFTER_ACTION, ['app\models\LogHandler', 'saveRequest'], ['request' => Yii::$app->request->getRawBody(), 'response' => Yii::$app->response->content]);

class UserController extends ActiveController
{

    public $modelClass = 'app\models\User';

    public function behaviors()
    {
        $behaviors = parent::behaviors();

        $behaviors['contentNegotiator']['formats']['text/html'] = Response::FORMAT_XML;

        return $behaviors;
    }

    // POST demo
    public function actionDemo()
    {
        $data = array('status' => 200, 'message' => 'Success');
        return $data;
    }

}

在上面的代码中,如果你注意到了,那么我使用了类级别的事件处理程序(doc)。在这里,我试图捕获Controllers EVENT_AFTER_ACTION事件并将Request&Response对象传递给我LogHandlerstatic方法。但是,在我的处理程序中,我能够获取请求的原始正文,但无法获取actionDemo()返回的响应数据。

日志处理程序

namespace app\models;

use yii\db\ActiveRecord;

class LogHandler extends ActiveRecord
{
    public static function tableName()
    {
        return 'request_log';
    }

    public static function saveRequest($event)
    {
//        self::load($event);
//        self::save();
        var_dump($event);
    }

}

我如何获得响应数据以及...

4

1 回答 1

2

根据这里的 Yii 指南,创建记录器组件的最佳方法是覆盖类 yii\log\Target。然后发送日志,需要重写这个类的抽象方法export()

由于这个类是在请求的生命周期之后被访问的,你将拥有请求和响应数据Yii::$app->requestYii::$app->response并且你可以访问它们来创建你想要的任何消息。这是 LogHandler 类的示例(可以对其进行编辑以包含您想要的有关请求和响应的任何详细信息)

namespace app\models;

use yii\db\ActiveRecord;

class LogHandler extends ActiveRecord {
    $requestPath;
    $responseBody;

    public static function tableName() {
        return 'request_log';
    }    
}

一个记录器类的例子如下:

namespace app\components\Logs;

use yii\helpers\VarDumper;
use yii\log\Target;
use Yii;

class LoggerComponent extends Target {

    public function export() {
        $logMessage = new LogHandler();
        $logMessage->requestPath = VarDumper::export(Yii::$app->request->absoluteUrl);
        $logMessage->responseBody = VarDumper::export(Yii::$app->response->data);
        $logMessage->save();
    }

}
于 2018-11-19T12:21:43.440 回答