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();
// ...
}
}
首先创建基本中间件,如
此文档中所述
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
在发出准备好的语句时使用。