Symfony,getter和setter与魔术方法

5
我不喜欢为实体类的每个属性都编写“愚蠢”的getter和setter,所以我考虑使用魔术方法来代替创建每个单独的getter和setter。这个想法是在逻辑与典型的“return $name”或“$this-> name = $name”不同的情况下创建特定的getter或setter。此外,这个魔术方法将在一个不同的类中创建,并且每个实体类都会扩展它(我还没有考虑很多这个步骤)。
无论如何,您认为用魔术方法替换getter/setter如何?这会对性能产生太大的影响吗?还有其他问题我没有考虑到吗?

1
获取器和设置器允许你控制对象的API。你可能需要一个setContainer方法,它只允许接受ContainerInterface对象作为参数,这是很难通过魔术设置方法实现的。此外,它还可以轻松地添加或更改特定获取器/设置器的行为。 - Touki
3个回答

2
这样做的问题在于,例如symfony2的默认模板引擎twig需要这些方法。Twig将语句{{ object.property }}转换为$object->getProperty(),因此您不得不像这样在twig中调用属性,而不是使用非常好的点符号表示法:{{ object.__get("property") }}
我知道doctrine在其实体管理器中也使用魔术方法。因此,当您为对象进行存储库查询时,可以使用以下命令:
 $repository->findOneByProperty($value);

替代

$repository->findOneBy(array(
    'property' => $value
));

我强烈建议您不要使用魔术方法,而是为每个属性单独使用一个getset方法。这样做还可以更好地控制该属性的状态。
另外,请确保查看此答案。它几乎也回答了您的问题。

说实话,我不知道为什么Symfony从未根据实体ORM定义自动定义这些内部内容...我的意思是,也许在输入或跟踪时,您的代码编辑器自动查找要建议的函数很好,但实际上,我必须使用插件来跟踪许多Symfony内置的东西,因此默认情况下缺少一些“智能”行为并没有太大的区别。我认为获取器和设置器(特别是名称/大小写转换)是原始人做ORM实体的方式。它应该是聪明和直观的开箱即用,而不是一堆繁琐的工作。 - SteveExdia

2

如果您正在引用Doctrine Entity,并且不反对代码生成,您可以使用doctrine:generate:entities命令,例如:

$ php app/console doctrine:generate:entities Acme/StoreBundle/Entity/Product

文档所述。

因此,您只需要指定字段即可。


这是一个不必手动输入getter/setter的好解决方案,但对我来说,根本问题在于必须首先拥有它们。试图弄清楚由之前的开发人员定义的实体类,其中包含数十个getter/setter和自定义函数,其中许多看起来与getter/setter模糊不清,在许多项目中已经成为我和其他人反复头痛的问题。 - SteveExdia

1

在这种情况下,IDE中的代码补全功能将无法使用。 此外,您将无法为对象和数组进行类型提示,也无法使用文档块。 性能会变慢,但根据您的项目(服务器硬件和用户数量)可能不会有任何差异


我同意这一点,有时候编写 getters 和 setters 是件很烦人的任务,但你也应该更加深入地思考它们。有时候你甚至会发现其实并不需要它们,因为有些属性根本就没有被外部使用。而且,大多数现代 IDE 都提供了非常好的支持,可以帮助你轻松创建这些方法。 - m0c
同样的事情如在 PHP Storm 中重构将无法工作,因为 setter 和 getter 只存在于虚拟状态。 - Lazy Ants
1
代码补全可以很好地与类文档块中的@property标签配合使用(主要IDE支持它)。 - Leto
很多代码完成和智能编辑器跟踪/建议已经无法在Symfony的编辑器中直接使用。目前最受欢迎的PHP编辑器JetBrains不理解许多重要的预构建Symfony标准或定义,我必须使用插件。Symfony不依赖硬编码的getter/setter意味着一个插件将有能力识别自动化的那些,并且通过一个良好的模式(并不难做到),该插件就不需要太多工作来实现。Laravel已经是这种情况的一个例子,而且它是一个更受欢迎的框架。 - SteveExdia

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接