Symfony v6.3 中的弃用:不推荐将“App\DQL\TablePrefixSubscriber”注册为 Doctrine 订阅者
我通过Doctrine官方方法和StackOverflow答案在数据库中的表中使用前缀。
升级到 Symfony v6.3 后得到新的弃用:
用户已弃用:自 symfony/doctrine-bridge 6.3 起:已弃用将“App\DQL\TablePrefixSubscriber”注册为 Doctrine 订阅者。相反,使用例如将其注册为侦听器#[AsDoctrineListener] 属性。
相关部分
services.yaml
parameters:
app.db_table_prefix: abc_
services:
app.tbl_prefix_subscriber:
class: App\DQL\TablePrefixSubscriber
arguments: [%app.db_table_prefix%]
tags:
- { name: doctrine.event_subscriber }
我现在的
TablePrefixSubscriber
<?php
namespace App\DQL;
use Doctrine\ORM\Event\LoadClassMetadataEventArgs;
use Doctrine\Common\EventSubscriber as EventSubscriber;
use Doctrine\ORM\Mapping\ClassMetadataInfo as ClassMetadataInfo;
class TablePrefixSubscriberNew implements EventSubscriber
{
protected string $prefix = '';
public function __construct(string $prefix)
{
$this->prefix = $prefix;
}
public function getSubscribedEvents(): array
{
return array('loadClassMetadata');
}
public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs): void
{
$classMetadata = $eventArgs->getClassMetadata();
if (!$classMetadata->isInheritanceTypeSingleTable() || $classMetadata->getName() === $classMetadata->rootEntityName) {
$classMetadata->setPrimaryTable([
'name' => $this->prefix . $classMetadata->getTableName()
]);
}
foreach ($classMetadata->getAssociationMappings() as $fieldName => $mapping) {
if ($mapping['type'] === ClassMetadataInfo::MANY_TO_MANY && $mapping['isOwningSide']) {
$mappedTableName = $mapping['joinTable']['name'];
$classMetadata->associationMappings[$fieldName]['joinTable']['name'] = $this->prefix . $mappedTableName;
}
}
}
}
遵循弃用通知中的建议并进行少量重构后,我找到了工作解决方案。
相关部分
services.yaml
parameters:
app.db_table_prefix: abc_
services:
App\DQL\TablePrefixListener:
arguments:
$prefix: '%app.db_table_prefix%'
public: true
当前
TablePrefixListener
<?php
namespace App\DQL;
use Doctrine\Bundle\DoctrineBundle\Attribute\AsDoctrineListener;
use Doctrine\ORM\Event\LoadClassMetadataEventArgs;
use Doctrine\ORM\Events;
use Doctrine\ORM\Mapping\ClassMetadataInfo as ClassMetadataInfo;
/*
* Setup information directly from Doctrine
* https://www.doctrine-project.org/projects/doctrine-orm/en/2.16/cookbook/sql-table-prefixes.html#telling-the-entitymanager-about-our-listener
* https://symfony.com/doc/current/doctrine/events.html#doctrine-entity-listeners
*/
#[AsDoctrineListener(event: Events::loadClassMetadata, priority: 500, connection: 'default')]
class TablePrefixListener
{
protected string $prefix = '';
public function __construct(string $prefix)
{
$this->prefix = $prefix;
}
public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs): void
{
$classMetadata = $eventArgs->getClassMetadata();
if (!$classMetadata->isInheritanceTypeSingleTable() || $classMetadata->getName() === $classMetadata->rootEntityName) {
$classMetadata->setPrimaryTable([
'name' => $this->prefix . $classMetadata->getTableName()
]);
}
foreach ($classMetadata->getAssociationMappings() as $fieldName => $mapping) {
if ($mapping['type'] === ClassMetadataInfo::MANY_TO_MANY && $mapping['isOwningSide']) {
$mappedTableName = $mapping['joinTable']['name'];
$classMetadata->associationMappings[$fieldName]['joinTable']['name'] = $this->prefix . $mappedTableName;
}
}
}
}