【问题标题】:Force Repository to return CustomClass type instead of Object type强制存储库返回 CustomClass 类型而不是 Object 类型
【发布时间】:2023-04-09 02:43:02
【问题描述】:

在我的 Symfony 4、Doctrine 2 和 PHP 7.2 项目中,我有一个名为 Location 的实体和一个 LocationRepository(从 Doctrine 的 ServiceEntityRepository 扩展而来)。

我正在实现一个 findLocationByUuid 方法,其中给定一个字符串,返回一个位置:

public function getLocationByUuid(string $uuid): Location
{
    $location = $this->findOneBy(['uuid' => $uuid]);

    if (null == $location) {
        throw new LocationNotFoundException();
    }

    return $location;
}

由于 Doctrine 的 findOneBy 方法返回一个 Object,那么在方法中严格符合我的返回类型声明并返回 Location 的最佳方式是什么? em> 而不是一个对象?我是否应该假设这个 Object 与我的 Locations 具有相同的行为并将 Object 声明为返回类型?

【问题讨论】:

  • LocationRepository :: findOneBy 将始终返回一个 Location 假设找到一个。无需担心它会返回其他东西。这正是 Doctrine Repositories 的工作方式。我想如果您的 IDE 抱怨,那么您可以随时进行类型转换。
  • @Cerad 完全正确。我可以忽略我的 IDE 对我的第二个问题回答“是”,但对我来说仍然不好看。检查对象的 instandeof 将是一个解决方案,但它似乎有点没用。在 PHP 中转换自定义类非常棘手和肮脏,我认为它不干净。
  • 要让 IDE 安静下来,您可以将 @method findOneby(array $criteria, array $orderBy = null): ?Location 添加到存储库类的 DocBLock 中。
  • 实际上,通过类型转换,我的意思更像是“/** @var Location */”,它告诉 IDE 你有一个 Location 对象。虽然我不明白为什么 $location = (Location) $this->findOneBy 不起作用。但 '@var' 应该是你所需要的。
  • @Cerad 在 PHP 中只能转换为原始类型。 $location = (Location) $this->findOneBy 无效。

标签: php symfony doctrine php-7 return-type


【解决方案1】:

Symfony 4 ./bin/console make:entity 命令创建实体和存储库类。存储库类具有注释的方法,例如,所以你的问题应该得到解决

/**
 * @method TinyPuppy|null find($id, $lockMode = null, $lockVersion = null)
 * @method TinyPuppy|null findOneBy(array $criteria, array $orderBy = null)
 * @method TinyPuppy[]    findAll()
 * @method TinyPuppy[]    findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
 */
class TinyPuppyRepository extends ServiceEntityRepository

【讨论】:

    【解决方案2】:

    Doctrine 的 findOneBy 是通用的,因此它不能强制将 Location 作为返回类型。在你的情况下,我会做的是,而不是检查位置是否为空,我会检查它是否是 Location 的实例,所以:

    if (!$location instanceof Location) {
        throw new LocationNotFoundException();
    }
    

    这样你就可以确定如果你的方法返回了一些东西,那就是Location

    【讨论】:

    • Doctrines findOneBy 要么返回指定类型的对象,要么返回 null,因此您的代码的行为与 OP 相同(尽管与 null 比较时,我会使用 === 而不是== - 但大多数时候这是个人喜好)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-28
    • 2013-11-01
    • 2011-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多