【发布时间】:2015-08-06 10:20:59
【问题描述】:
我是在 symfony 框架的上下文中问的。
我想知道这是否是使用魔法查找方法(如 find($id)、findByField($value) 等...)的好习惯。
这些方法既没有返回类型也没有定义。这导致我的 IDE 在它们周围标记警告。此外,我必须在使用这些方法时一直标记返回值的类型,以使代码完成对这些变量起作用。
作为一种解决方案,我通常在自定义存储库类中编写 getter。在 symfony 文档中有这样的 getter 示例,它重载了魔法 findBy 方法的变体。
我对这种重载的魔法查找方法也有不好的感觉,因为它有点混合了我自己的 repo 实现与父 EntityRepository 的实现。
所以我最终编写了使用“get”前缀而不是“find”的自定义 getter。
现在,谁能告诉我最佳做法是什么以及为什么?
编辑
最近我在寻找一些优化学说的方法,我发现建议不要使用魔法探测器,所以这是反对魔法探测器的另一个论点。
我还阅读了有关魔法探测器的教义文档,发现: http://docs.doctrine-project.org/projects/doctrine1/en/latest/en/manual/dql-doctrine-query-language.html#magic-finders
这些是非常有限的魔法查找器,始终建议您将查询扩展为手动编写的 DQL 查询。这些方法仅用于快速访问单个记录,没有关系,并且有利于快速制作代码原型。
所以我终于对魔法探测器提出了自己的意见(和用例)。仅将它们用于加快编码速度,并始终使用 TODO 标记它们,以便在清理代码的同时将它们重写为自定义存储库方法。
【问题讨论】:
-
在我看来,对这类任务使用代码注释是正确的方法:重新定义所有(或部分)方法是完全没用的,并且可能会使您面临错误问题和类似问题。
-
我个人认为使用这些神奇的方法是不好的做法。我发现为每个实体实现一个具体的存储库类要好得多。我什至更进一步,不会扩展 EntityRepository,而是装饰它,因此我可以完全控制我的存储库类的 API。
-
我同意@DonCallisto 和@Gerry。如果需要,我决定使用
findBy()/findOneBy()而不是魔法方法... -
@Gerry - 但是你用修饰的存储库实现了什么?对于自定义查询,您将不得不公开其受保护的成员 _em,这对我来说没有多大意义。此外,IMO 可以更好地扩展存储库并使用整个查询构建编写自定义 getter,因为它允许您优化查询。如果您的实体之间有许多关系,则包装魔术查找方法,然后再询问所获取实体的相关实体,将对数据库产生多个查询。使用自定义 getter,您可以使用适合这种情况的连接构建查询。
标签: php symfony doctrine-orm coding-style