Symfony v6.3中的弃用:将“App\DQL\TablePrefixSubscriber”注册为Doctrine订阅者已弃用

nbewdwxp  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(118)

Symfony v6.3中的弃用:将“App\DQL\TablePrefixSubscriber”注册为Doctrine订阅者已弃用

简介

通过Doctrine官方方法和StackOverflow answer的方法,在数据库中使用了一个表前缀。

问题

升级到Symfony v6.3后,有了新的弃用:
用户弃用:由于symfony/doctrine-bridge 6.3:不建议将“App\DQL\TablePrefixSubscriber”注册为Doctrine订阅者。请使用#[AsDoctrineSubscribe]属性将其注册为侦听器。

代码

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;
            }
        }
    }
}
anhgbhbe

anhgbhbe1#

一个答案

在遵循了弃用通知中的建议和少量的重构之后,我得到了工作解决方案。

代码

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;
            }
        }
    }
}

相关问题