既然“setSQLLogger()”已被弃用,如何使用中间件在 Doctrine 3 中记录查询执行时间?

问题描述 投票:0回答:1

Doctrine 已弃用其

->setSQLLogger()
,转而支持中间件。

我找不到任何方法来记录查询的开始和结束以获取执行时间。

以前可以像关于 Symfony2 的问题一样完成。

我应该创建什么样的中间件才能记录查询的执行时间?

现在,我只启用了日志记录,但这只是在执行查询之前记录查询。

我发现所有查询都被收集在
DebugDataHolder

内,因此作为替代方案,可以在请求结束时记录所有查询:

use Doctrine\SqlFormatter\SqlFormatter;

class DatabaseFormatter implements FormatterInterface
{
    private string $id;
    private SqlFormatter $formatter;

    public function __construct(
        private DebugDataHolder $dataHolder,
    ) {
    }

    public function afterRequest() 
    {
        $queries = $this->dataHolder->getData();

        // ...
    }
}


php symfony doctrine middleware
1个回答
1
投票

首先创建基本中间件,如

此文档

中所述 namespace App\Doctrine; use Doctrine\DBAL\Driver as DriverInterface; use Doctrine\DBAL\Driver\Middleware as MiddlewareInterface; class Middleware implements MiddlewareInterface { public function __construct( /* ...dependencies from Symfony DI */ ) { } public function wrap(DriverInterface $driver): Driver { // \App\Doctrine\Driver return new Driver($driver, /* ...dependencies */); } }

然后添加额外的中间件:

namespace App\Doctrine; use Doctrine\DBAL\Driver as DriverInterface; use Doctrine\DBAL\Driver\Middleware\AbstractDriverMiddleware; final class Driver extends AbstractDriverMiddleware { public function __construct( DriverInterface $driver, /* ...dependencies */ ) { parent::__construct($driver); } public function connect(array $params): Connection { // \App\Doctrine\Connection return new Connection(parent::connect($params), /* ...dependencies */); } }

namespace App\Doctrine;

use App\Log\Formatter\DatabaseFormatter;
use Doctrine\DBAL\Driver\Connection as ConnectionInterface;
use Doctrine\DBAL\Driver\Middleware\AbstractConnectionMiddleware;
use Doctrine\DBAL\Driver\Result;
use Doctrine\DBAL\Driver\Statement as StatementInterface;

class Connection extends AbstractConnectionMiddleware
{
    public function __construct(
        ConnectionInterface $connection,
    ) {
        parent::__construct($connection);
    }

    public function prepare(string $sql): StatementInterface
    {
        // \App\Doctrine\Driver
        return new Statement(parent::prepare($sql), $sql);
    }

    /*
     * Overwrite any method from parent class with features
     */
}
namespace App\Doctrine;

use Doctrine\DBAL\Driver\Middleware\AbstractStatementMiddleware;
use Doctrine\DBAL\Driver\Statement as StatementInterface;

final class Statement extends AbstractStatementMiddleware
{
    private array $params = [];
    private array $types = [];

    public function __construct(
        StatementInterface $statement,
        private string $sql,
    ) {
        parent::__construct($statement);
    }

    /*
     * Overwrite any method from parent class with features.
     */
}

Connection

类在发出直接请求时使用,

Statement
在发出准备好的语句时使用。
    

© www.soinside.com 2019 - 2024. All rights reserved.