背景
我正在使用Symfony 2开发一个应用程序,其结构使得"Core"包定义实体,关系和字段.然后,其他捆绑包可以通过继承来专门化核心功能,即所谓的"子"捆绑包.
Doctrine 2注释已用于定义称为"Package"的核心实体."包装"将建筑设计和一块土地联系在一起 - 基本上是一个房屋和土地包.我已经将示例切换回更基本的形式,因此您不会在下面的示例中找到Land和ChildLand的定义,但您可以假设它们已经以类似的方式实现.
更新
根据FreeNode的#symfony频道上的用户,这是一个学说问题,因为app/console命令只是调用了教条控制台.我正在使用学说2.3.
下面的图表显示了导致问题可能有助于可视化场景的一般情况:
此外,这里还有关于学说问题跟踪器的错误报告的链接:http://www.doctrine-project.org/jira/browse/DDC-2605
更新2 - 更详细的ERD
实体之间关系的结构受到质疑,因此下面是我们正在实施的数据结构的一个更好的例子.
主要要求是再次拥有提供共享实体和字段集的核心类.公司包中的子类扩展了这些核心类.
我们确实考虑了EAV的长度,但在这种方法中,我们将花费更多时间创建平台和管理EAV数据的工具而不是满足当前的业务需求,我们将无法使用学说来管理实体它们将在数据库等中定义等.
随着时间的推移,我开始更好地理解这个问题,似乎唯一的问题是由doctrine的CLI工具生成的getter和setter,因为它们打破了类型提示合同,如下所述.当手动纠正这些问题时,此结构非常有效.
使用CLI工具生成实体
所以,最初我使用命令行工具......
> app/console doctrine:generate:entity
Run Code Online (Sandbox Code Playgroud)
...使用基本字段映射生成实体存根,然后手动将关系添加到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
Run Code Online (Sandbox Code Playgroud)
这会自动修改核心和子实体定义:
核心包实体: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)
Run Code Online (Sandbox Code Playgroud)
错误:(
不幸的是,不同类型的提示导致PHP严格错误发生,例如:
PHP Fatal error: …Run Code Online (Sandbox Code Playgroud)