Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/275.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何从两个实体存储库中删除类似的条令功能?_Php_Symfony_Doctrine Orm_Symfony4 - Fatal编程技术网

Php 如何从两个实体存储库中删除类似的条令功能?

Php 如何从两个实体存储库中删除类似的条令功能?,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); } ...

我用的是symfony4

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是解耦的。我在一篇文章中扩展了这种方法