使用当前的 symfony 5.3 和教义 2.9.5
在您的配置中定义服务和教义.orm.repository_factory:
doctrine:
orm:
#Replace repository factory
repository_factory: 'MyBundle\Factory\RepositoryFactory'
services:
MyBundle\Factory\RepositoryFactory:
arguments: [ '@router', '@translator', '%kernel.secret%' ]
添加您的 MyBundle/Factory/RepositoryFactory.php 文件:
<?php declare(strict_types=1);
namespace MyBundle\Factory;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Repository\RepositoryFactory as RepositoryFactoryInterface;
use Doctrine\Persistence\ObjectRepository;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
/**
* This factory is used to create default repository objects for entities at runtime.
*/
final class RepositoryFactory implements RepositoryFactoryInterface {
/**
* The list of EntityRepository instances
*
* @var ObjectRepository[]
*/
private $repositoryList = [];
/**
* The kernel secret
*
* @var string
*/
private $secret;
/**
* The RouterInterface instance
*
* @var RouterInterface
*/
private $router;
/**
* The TranslatorInterface instance
*
* @var TranslatorInterface
*/
private $translator;
/**
* Initializes a new RepositoryFactory instance
*
* @param RouterInterface $router The router instance
* @param TranslatorInterface $translator The TranslatorInterface instance
* @param string $secret The kernel secret
*/
public function __construct(RouterInterface $router, TranslatorInterface $translator, string $secret) {
//Set router
$this->router = $router;
//Set secret
$this->secret = $secret;
//Set translator
$this->translator = $translator;
}
/**
* {@inheritdoc}
*/
public function getRepository(EntityManagerInterface $entityManager, $entityName): ObjectRepository {
//Set repository hash
$repositoryHash = $entityManager->getClassMetadata($entityName)->getName() . spl_object_hash($entityManager);
//With entity repository instance
if (isset($this->repositoryList[$repositoryHash])) {
//Return existing entity repository instance
return $this->repositoryList[$repositoryHash];
}
//Store and return created entity repository instance
return $this->repositoryList[$repositoryHash] = $this->createRepository($entityManager, $entityName);
}
/**
* Create a new repository instance for an entity class
*
* @param EntityManagerInterface $entityManager The EntityManager instance.
* @param string $entityName The name of the entity.
*/
private function createRepository(EntityManagerInterface $entityManager, string $entityName): ObjectRepository {
//Get class metadata
$metadata = $entityManager->getClassMetadata($entityName);
//Get repository class
$repositoryClass = $metadata->customRepositoryClassName ?: $entityManager->getConfiguration()->getDefaultRepositoryClassName();
//Return repository class instance
//XXX: router, translator and secret arguments will be ignored by default
return new $repositoryClass($entityManager, $metadata, $this->router, $this->translator, $this->secret);
}
}
然后定义你的 MyBundle/Repository/EntityRepository.php:
<?php declare(strict_types=1);
namespace MyBundle\Repository;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository as BaseEntityRepository;
use Doctrine\ORM\Mapping\ClassMetadata;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
/**
* EntityRepository
*
* {@inheritdoc}
*/
class EntityRepository extends BaseEntityRepository {
/**
* The RouterInterface instance
*
* @var RouterInterface
*/
protected RouterInterface $router;
/**
* The table keys array
*
* @var array
*/
protected array $tableKeys;
/**
* The table values array
*
* @var array
*/
protected array $tableValues;
/**
* The TranslatorInterface instance
*
* @var TranslatorInterface
*/
protected TranslatorInterface $translator;
/**
* The kernel secret
*
* @var string
*/
protected string $secret;
/**
* Initializes a new LocationRepository instance
*
* @param EntityManagerInterface $manager The EntityManagerInterface instance
* @param ClassMetadata $class The ClassMetadata instance
* @param RouterInterface $router The router instance
* @param TranslatorInterface $translator The TranslatorInterface instance
* @param string $secret The kernel secret
*/
public function __construct(EntityManagerInterface $manager, ClassMetadata $class, RouterInterface $router, TranslatorInterface $translator, string $secret) {
//Call parent constructor
parent::__construct($manager, $class);
//Set secret
$this->secret = $secret;
//Set router
$this->router = $router;
//Set slugger
$this->slugger = $slugger;
//Set translator
$this->translator = $translator;
//Get quote strategy
$qs = $manager->getConfiguration()->getQuoteStrategy();
$dp = $manager->getConnection()->getDatabasePlatform();
//Set quoted table names
//XXX: remember to place longer prefix before shorter to avoid strange replacings
$tables = [
'MyBundle:UserGroup' => $qs->getJoinTableName($manager->getClassMetadata('MyBundle:User')->getAssociationMapping('groups'), $manager->getClassMetadata('MyBundle:User'), $dp),
'MyBundle:Group' => $qs->getTableName($manager->getClassMetadata('MyBundle:Group'), $dp),
'MyBundle:User' => $qs->getTableName($manager->getClassMetadata('MyBundle:User'), $dp),
//XXX: Set limit used to workaround mariadb subselect optimization
':limit' => PHP_INT_MAX,
"\t" => '',
"\n" => ' '
];
//Set quoted table name keys
$this->tableKeys = array_keys($tables);
//Set quoted table name values
$this->tableValues = array_values($tables);
}
}
然后在 MyBundle/Repository/UserRepository.php 中简单地扩展它:
<?php declare(strict_types=1);
namespace MyBundle\Repository;
/**
* UserRepository
*/
class UserRepository extends EntityRepository {
}