我有一个加载大量数据的装置,但我总是遇到这个错误:
Fatal error: Allowed memory size of 2147483648 bytes exhausted (tried to allocate 16777224 bytes) in /var/www/html/platform-cm/vendor/doctrine/dbal/lib/Doctrine/DBAL/Logging/DebugStack.php on line 65
[Symfony\Component\Debug\Exception\OutOfMemoryException] Error: Allowed memory size of 2147483648 bytes exhausted (tried to allocate 16777224 bytes)
经过一番研究我发现this在我读到日志记录可能是问题原因的帖子中,因为 AppKernel
实例化时 debug 默认设置为 true,然后 SQL 命令在每次迭代时都存储在内存中。
在 AppKernel
上不禁用调试的第一次尝试运行命令如下:
doctrine:fixtures:load --no-debug
但我没有得到运气,因为同样的错误仍然存在。
第二次尝试是在 config_dev.yml
中禁用调试,但不推荐这样做,因为我正在获取所有日志,但都没有用。
monolog:
handlers:
main:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.log"
level: debug
# console:
# type: console
# bubble: false
# verbosity_levels:
# VERBOSITY_VERBOSE: INFO
# VERBOSITY_VERY_VERBOSE: DEBUG
# channels: ["!doctrine"]
# console_very_verbose:
# type: console
# bubble: false
# verbosity_levels:
# VERBOSITY_VERBOSE: NOTICE
# VERBOSITY_VERY_VERBOSE: NOTICE
# VERBOSITY_DEBUG: DEBUG
# channels: ["doctrine"]
所以,这就是我的夹具的样子:
class LoadMsisdn extends AbstractFixture implements OrderedFixtureInterface
{
public function getOrder()
{
return 13;
}
public function load(ObjectManager $manager)
{
$content = file_get_contents('number.txt');
$numbers = explode(',', $content);
shuffle($numbers);
foreach ($numbers as $key => $number) {
$msisdn = new Msisdn();
$msisdn->setMsisdn($number);
$msisdn->setBlocked((rand(1, 1000) % 10) < 7);
$msisdn->setOperator($this->getReference('operator-' . rand(45, 47)));
$this->addReference('msisdn-' . $key, $msisdn);
$manager->persist($msisdn);
}
$manager->flush();
}
}
如果我需要从 EntityManager
禁用记录器,如同一帖子的答案所示,我该如何禁用记录器?
$em->getConnection()->getConfiguration()->setSQLLogger(null);
最佳答案
传递给load
方法的对象管理器是实体管理器的一个实例(Doctrine\Common\Persistence\ObjectManager
只是一个接口(interface),实体/文档/等管理人员实现)。
这意味着您可以使用与问题中相同的命令来使 SQL 记录器无效,例如..
$manager->getConnection()->getConfiguration()->setSQLLogger(null);
需要注意的是,DBAL 连接的默认日志记录设置是 %kernel.debug%
这意味着,除非您在配置中覆盖了它,否则日志记录应该只发生在 dev
环境。我可以看到您已尝试使用 --no-debug
选项,但我只能假设,因为记录器已设置 during the container compilation ,它不会将其取消设置为未重建的容器。
测试用例中的 Symfony 3/4/5 方法
final class SomeTestCase extends KernelTestCase
{
protected function setUp(): void
{
$this->bootKernel('...');
// @see https://stackoverflow.com/a/35222045/1348344
// disable Doctrine logs in tests output
$entityManager = self::$container->get(EntityManagerInterface::class);
$entityManager->getConfiguration();
$connection = $entityManager->getConnection();
/** @var Configuration $configuration */
$configuration = $connection->getConfiguration();
$configuration->setSQLLogger(null);
}
}
关于php - 如何在加载 Doctrine 固定装置时禁用控制台中的查询日志记录?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35192173/