[英]Using Symfony 2 CLI tools, how can I generate getters and setters with correct type hinting for sub-classes?
Background 背景
I am developing an application using Symfony 2 that is structured such that a "Core" bundle defines entities, relationships and fields. 我正在使用Symfony 2开发一个应用程序,其结构使得“Core”包定义实体,关系和字段。 Other bundles are then be able specialise the core functionality by inheritance, so-called "child" bundles.
然后,其他捆绑包可以通过继承来专门化核心功能,即所谓的“子”捆绑包。
Doctrine 2 annotations have been used to define a core entity called "Package". Doctrine 2注释已用于定义称为“Package”的核心实体。 A "Package" links together an architectural design and a piece of land - essentially a house-and-land package.
“包装”将建筑设计和一块土地联系在一起 - 基本上是一个房屋和土地包。 I've cut the examples back to a more basic form, so you won't find definitions for Land and ChildLand in the examples below, but you can assume they have been implemented in a similar fashion.
我已经将示例切换回更基本的形式,因此您不会在下面的示例中找到Land和ChildLand的定义,但您可以假设它们已经以类似的方式实现。
Update 更新
According to users on FreeNode's #symfony channel, this is a doctrine issue as the app/console command simply invokes the doctrine console. 根据FreeNode的#symfony频道上的用户,这是一个学说问题,因为app / console命令只是调用了教条控制台。 I am using doctrine 2.3.
我正在使用学说2.3。
Here is a diagram showing the general situation that causes the issue which should help visualise the scenario: 下面的图表显示了导致问题可能有助于可视化场景的一般情况:
( imgur link to full-size image ) ( imgur链接到完整大小的图像 )
Also, here is a link to a bug report on doctrine's issue tracker: http://www.doctrine-project.org/jira/browse/DDC-2605 此外,这里还有关于学说问题跟踪器的错误报告的链接: http : //www.doctrine-project.org/jira/browse/DDC-2605
Update 2 - More detailed ERD 更新2 - 更详细的ERD
The structure of the relationships between entities has been questioned, so below is a better example of the data structure we are implementing. 实体之间关系的结构受到质疑,因此下面是我们正在实施的数据结构的一个更好的例子。
The main requirement is again to have core classes that provide a shared set of entities and fields. 主要要求是再次拥有提供共享实体和字段集的核心类。 Child classes in company bundles extend these core classes.
公司包中的子类扩展了这些核心类。
We did consider EAV at length, but in that approach we will spend a lot more time creating a platform and the tools to manage EAV data rather than satisfying the present business requirements, we won't be able to use doctrine to manage the entities as they will be defined in the database, etc etc. 我们确实考虑了EAV的长度,但在这种方法中,我们将花费更多的时间来创建平台和管理EAV数据的工具,而不是满足当前的业务需求,我们将无法使用学说来管理实体它们将在数据库等中定义等。
As time passes and I come to understand this issue better, it appears the only issue is with the getters and setters generated by doctrine's CLI tool as they break the type hinting contracts as mentioned below. 随着时间的推移,我开始更好地理解这个问题,似乎唯一的问题是由doctrine的CLI工具生成的getter和setter,因为它们打破了类型提示合同,如下所述。 This structure works perfectly when these issues are manually corrected.
当手动纠正这些问题时,此结构非常有效。
( imgur link to full-size image ) ( imgur链接到完整大小的图像 )
Generating Entities with CLI Tool 使用CLI工具生成实体
So, initially I used the command line tool... 所以,最初我使用命令行工具......
> app/console doctrine:generate:entity
...to generate the entity stubs with basic field mappings, then manually added the relationship to land (as the tool doesn't seem to support relationships): ...使用基本字段映射生成实体存根,然后手动将关系添加到land(因为该工具似乎不支持关系):
This is the resulting code: 这是结果代码:
core Package entity: http://pastebin.com/3ujPT1mJ 核心包实体: http : //pastebin.com/3ujPT1mJ
child Package entity: http://pastebin.com/sjAB0XJ2 子包实体: http : //pastebin.com/sjAB0XJ2
Generating Getters and Setters 生成Getters和Setter
Next, I generate the getters and setters by executing: 接下来,我通过执行以下命令生成getter和setter:
> app/console doctrine:generate:entities CompanyCoreBundle
> app/console doctrine:generate:entities CompanyChildBundle
Which automatically modifies the core and child entity definitions: 这会自动修改核心和子实体定义:
core Package entity: http://pastebin.com/kfQRxcnm 核心包实体: http : //pastebin.com/kfQRxcnm
child Package entity: http://pastebin.com/UdiPP9xX 子包实体: http : //pastebin.com/UdiPP9xX
The problem! 问题!
So, the crux of the issue is this: If you compare the setLand function in the Core and Child bundle, you can see the declarations are different: 因此,问题的关键在于:如果比较Core和Child包中的setLand函数,您可以看到声明不同:
public function setLand(\Company\CoreBundle\Entity\Land $land = null)
public function setLand(\Company\ChildBundle\Entity\ChildLand $land = null)
Errors :( 错误:(
Unfortunately, the different type hints cause PHP strict errors to occur, for example: 不幸的是,不同类型的提示导致PHP严格错误发生,例如:
PHP Fatal error: Class 'Symfony\Component\Debug\Exception\ContextErrorException' not found in ... Company/ChildBundle/Entity/ChildPackage.php on line ...
And 和
Runtime Notice: Declaration of ... should be compatible with ... in ... line ...
The cause of the errors 导致错误的原因
After doing some research as to why this was a problem, I read in several places that changing type hinting in subclasses breaks type hinting contracts (see this post: Is there a way to redefine a type hint to a descendant class when extending an abstract class? ). 在研究了为什么这是一个问题之后,我在几个地方读到,在子类中改变类型提示打破了类型提示契约(参见这篇文章: 有没有办法在扩展抽象类时将类型提示重新定义为后代类? )。
Options? 选项?
There are some obvious but less-than-ideal options: 有一些明显但不太理想的选择:
My question!!! 我的问题!!! (finally)
(最后)
My question is, is it possible to use the command line tools to do what I am trying to do here? 我的问题是,是否可以使用命令行工具来完成我在这里尝试做的事情? Ideally, I'd love to be able to execute the doctrine console commands to generate entity stubs and getters and setters without manual intervention to fix up type hints in sub-classes.
理想情况下,我希望能够执行doctrine控制台命令来生成实体存根和getter以及setter而无需手动干预来修复子类中的类型提示。 If this isn't easily achievable, what's the next-best option?
如果这不容易实现,那么下一个最佳选择是什么?
Gratitude 感谢
Thanks! 谢谢!
I'm not exactly sure what process you'll use in order to define the entities, but in order to usefully create persistable entities with Doctrine such as GenericEngine and FordEngine, you want @MappedSuperclass
我不确定你将使用什么过程来定义实体,但是为了有用地创建具有Doctrine的可持久实体,例如GenericEngine和FordEngine,你想要
@MappedSuperclass
http://docs.doctrine-project.org/en/latest/reference/inheritance-mapping.html#mapped-superclasses http://docs.doctrine-project.org/en/latest/reference/inheritance-mapping.html#mapped-superclasses
It's the Doctrine equivalent of an abstract class. 它是一个抽象类的学说等价物。
There are some other interesting inheritance tricks on that page linked above. 在上面链接的页面上还有一些其他有趣的继承技巧。 They might help you.
他们可能会帮助你。
As far as generating this stuff automatically, it could be doable but above my pay grade at +50 reputation points. 至于自动生成这些东西,它可能是可行的,但高于我的+50声望点的工资等级。 :-) Doctrine can help you generate code templates for your entities, but really, time designing the entities and their relationships is better spent than time coming up with a magic command line combination.
:-) Doctrine可以帮助您为实体生成代码模板,但实际上,设计实体及其关系的时间比花时间提出魔术命令行组合更好。
(Myself, I'd have a Manufacturer
entity and then have one-to-many relationship between the Engine
and the Manufacturer
. But that's not what you asked. :-) (我自己,我有一个
Manufacturer
实体,然后Engine
和Manufacturer
之间有一对多的关系。但那不是你问的。:-)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.