Php 如何从两个实体存储库中删除类似的条令功能?
我用的是symfony4Php 如何从两个实体存储库中删除类似的条令功能?,php,symfony,doctrine-orm,symfony4,Php,Symfony,Doctrine Orm,Symfony4,我用的是symfony4 namespace App\Repository; use ... class CountryRepository extends ServiceEntityRepository { public function __construct(RegistryInterface $registry) { parent::__construct($registry, Country::class); } ...
namespace App\Repository;
use ...
class CountryRepository extends ServiceEntityRepository
{
public function __construct(RegistryInterface $registry)
{
parent::__construct($registry, Country::class);
}
...
public function deleteMultipleByIds(array $ids): void
{
$builder = $this->createQueryBuilder('l');
$builder->delete()
->where('l.id IN(:ids)')
->setParameter(
':ids',
$ids,
Connection::PARAM_INT_ARRAY
);
$query = $builder->getQuery();
$query->execute();
}
CountryI18nRepository
类中存在相同的方法
我希望只有一个这样的函数,它只使用正确的实体(Country v CountryI18n)
如何以及在何处创建新类?如果该类属于
ServiceEntityRepository
类或其他类型?如果您的问题与复制有关,您可以创建一个GenericRepo
(不一定是一个条令存储库;请选择一个更好的名称),您可以在需要时注入并使用它
差不多
class GenericRepo
{
public function deleteMultipleByIds(QueryBuilder $qb, string $rootAlias, array $ids): void
{
$qb->delete()
->where(sprintf('%s.id IN(:ids)', $rootAlias))
->setParameter(':ids', $ids, Connection::PARAM_INT_ARRAY);
$qb->getQuery()->execute();
}
}
例如,在您的国家中,CountryI18nRepository
class CountryI18nRepository
{
private $genericRepo;
public function __construct(GenericRepo $genericRepo)
{
$this->genericRepo = $genericRepo;
}
public function deleteMultipleByIds(array $ids): void
{
$builder = $this->createQueryBuilder('l');
$this-> genericRepo->deleteMultipleByIds($builder, 'l', $ids);
}
}
您也可以从GenericRepo
进行扩展,但由于PHP只支持单一继承,因此最好(至少在我看来)使用上面所示的组合
免责声明
我没有测试这段代码,所以可能需要进行一些调整。顺便说一句,显示的概念是有效的。使用DeleteMultipleById创建一个抽象存储库,如:
abstract class BaseCountryRepository extends ServiceEntityRepository
并在其他存储库中扩展它,而不是ServiceEntityRepository
class CountryRepository extends BaseCountryRepository
class CountryI18nRepository extends BaseCountryRepository
您可以从这些类中删除deleteMultipleById定义,而不是创建自己的基本存储库类,您可以使用trait实现这一点。我自己还没有尝试过这个特定的用例,但我不明白为什么它不起作用。干净的方法是使用服务和组合而不是继承。请注意这些最终会导致继承地狱的解决方案。为什么?看,这就是你投反对票的原因?!尝试提供一个解决方案,如果您与symfony合作,您将知道这种方法在没有任何问题的情况下可以很好地工作drawbacks@TomášVotruba:我同意这是一个非常有效的继承用例。一个父类、一个中间类和两个实现类共享代码。在这种特殊情况下,问题出在哪里?@lxg根据我咨询50多个PHP项目的经验,“就在这里没问题”的方法会导致严重的遗留问题,这些问题很难解耦,因此从头开始编写应用程序是值得的。问题是,一门课从来都不是问题。这一决定在未来5年内的后果如下所示。请参阅参考文章。大多数“为什么”都有。@AbdelhafidElKadiri I在其余的评论中链接了解决方案。看见并非所有有效的方法都是正确的。此外,在框架供应商锁定中,要注意这一点。这是一个更好的解决方案,因为它与Symfony和Doctrine是解耦的。我在一篇文章中扩展了这种方法