繁体   English   中英

使用Symfony 2 CLI工具,如何为子类生成具有正确类型提示的getter和setter?

[英]Using Symfony 2 CLI tools, how can I generate getters and setters with correct type hinting for sub-classes?

背景

我正在使用Symfony 2开发一个应用程序,其结构使得“Core”包定义实体,关系和字段。 然后,其他捆绑包可以通过继承来专门化核心功能,即所谓的“子”捆绑包。

Doctrine 2注释已用于定义称为“Package”的核心实体。 “包装”将建筑设计和一块土地联系在一起 - 基本上是一个房屋和土地包。 我已经将示例切换回更基本的形式,因此您不会在下面的示例中找到Land和ChildLand的定义,但您可以假设它们已经以类似的方式实现。

更新

根据FreeNode的#symfony频道上的用户,这是一个学说问题,因为app / console命令只是调用了教条控制台。 我正在使用学说2.3。

下面的图表显示了导致问题可能有助于可视化场景的一般情况:

imgur链接到完整大小的图像 类型提示合同中断

此外,这里还有关于学说问题跟踪器的错误报告的链接: http//www.doctrine-project.org/jira/browse/DDC-2605

更新2 - 更详细的ERD

实体之间关系的结构受到质疑,因此下面是我们正在实施的数据结构的一个更好的例子。

主要要求是再次拥有提供共享实体和字段集的核心类。 公司包中的子类扩展了这些核心类。

我们确实考虑了EAV的长度,但在这种方法中,我们将花费更多的时间来创建平台和管理EAV数据的工具,而不是满足当前的业务需求,我们将无法使用学说来管理实体它们将在数据库等中定义等。

随着时间的推移,我开始更好地理解这个问题,似乎唯一的问题是由doctrine的CLI工具生成的getter和setter,因为它们打破了类型提示合同,如下所述。 当手动纠正这些问题时,此结构非常有效。

imgur链接到完整大小的图像 详细的数据结构

使用CLI工具生成实体

所以,最初我使用命令行工具......

> app/console doctrine:generate:entity

...使用基本字段映射生成实体存根,然后手动将关系添加到land(因为该工具似乎不支持关系):

这是结果代码:

核心包实体: http//pastebin.com/3ujPT1mJ

子包实体: http//pastebin.com/sjAB0XJ2

生成Getters和Setter

接下来,我通过执行以下命令生成getter和setter:

> app/console doctrine:generate:entities CompanyCoreBundle

> app/console doctrine:generate:entities CompanyChildBundle

这会自动修改核心和子实体定义:

核心包实体: http//pastebin.com/kfQRxcnm

子包实体: http//pastebin.com/UdiPP9xX

问题!

因此,问题的关键在于:如果比较Core和Child包中的setLand函数,您可以看到声明不同:

public function setLand(\Company\CoreBundle\Entity\Land $land = null)
public function setLand(\Company\ChildBundle\Entity\ChildLand $land = null)

错误:(

不幸的是,不同类型的提示导致PHP严格错误发生,例如:

PHP Fatal error:  Class 'Symfony\Component\Debug\Exception\ContextErrorException' not found in ... Company/ChildBundle/Entity/ChildPackage.php on line ...

Runtime Notice: Declaration of ... should be compatible with ... in ... line ...

导致错误的原因

在研究了为什么这是一个问题之后,我在几个地方读到,在子类中改变类型提示打破了类型提示契约(参见这篇文章: 有没有办法在扩展抽象类时将类型提示重新定义为后代类? )。

选项?

有一些明显但不太理想的选择:

  • 我可以很容易地压制严格的通知,但是我的开发经理不得不在我们的CI流程中创建雪花例外。
  • 我可以手动编辑doctrine生成的代码以删除所有类型提示,或者确保子类类型提示与父类相同。 这样做会使代码工作,但我可以看到它很乏味,除非我写一些脚本来为我管理这个。
  • 我不能使用命令行工具并手动手工制作我的实体和子实体。 我宁愿能用脚本自动化这个:(

我的问题!!! (最后)

我的问题是,是否可以使用命令行工具来完成我在这里尝试做的事情? 理想情况下,我希望能够执行doctrine控制台命令来生成实体存根和getter以及setter而无需手动干预来修复子类中的类型提示。 如果这不容易实现,那么下一个最佳选择是什么?

感谢

谢谢!

我不确定你将使用什么过程来定义实体,但是为了有用地创建具有Doctrine的可持久实体,例如GenericEngine和FordEngine,你想要@MappedSuperclass

http://docs.doctrine-project.org/en/latest/reference/inheritance-mapping.html#mapped-superclasses

它是一个抽象类的学说等价物。

在上面链接的页面上还有一些其他有趣的继承技巧。 他们可能会帮助你。

至于自动生成这些东西,它可能是可行的,但高于我的+50声望点的工资等级。 :-) Doctrine可以帮助您为实体生成代码模板,但实际上,设计实体及其关系的时间比花时间提出魔术命令行组合更好。

(我自己,我有一个Manufacturer实体,然后EngineManufacturer之间有一对多的关系。但那不是你问的。:-)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM