gpt4 book ai didi

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

转载 作者:IT王子 更新时间:2023-10-28 23:55:40 24 4
gpt4 key购买 nike

背景

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

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

更新

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

下图显示了导致问题的一般情况,应该有助于可视化场景:

( imgur link to full-size image )
Type hinting contract breaking

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

更新 2 - 更详细的 ERD

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

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

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

随着时间的流逝,我对这个问题有了更好的理解,似乎唯一的问题是由 dotric 的 CLI 工具生成的 getter 和 setter,因为它们违反了下面提到的类型提示契约(Contract)。当手动更正这些问题时,此结构可以完美运行。

( imgur link to full-size image )
Detailed data structure

使用 CLI 工具生成实体

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

> app/console doctrine:generate:entity

...生成具有基本字段映射的实体 stub ,然后手动将关系添加到土地(因为该工具似乎不支持关系):

这是结果代码:

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

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

生成 Getter 和 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 ...

错误原因

在做了一些关于为什么这是一个问题的研究之后,我在几个地方读到改变子类中的类型提示会破坏类型提示契约(Contract)(参见这篇文章: Is there a way to redefine a type hint to a descendant class when extending an abstract class?)。

选项?

有一些明显但不太理想的选择:
  • 我可以很容易地抑制严格的通知,但我的开发经理不愿在我们的 CI 过程中创建雪花异常的前景。
  • 我可以手动编辑学说生成的代码以删除所有类型提示,或确保子类类型提示与父类相同。这样做会使代码工作,但我可以看到它很乏味,除非我编写一些脚本来为我管理它。
  • 我不能使用命令行工具并手动手工制作我的实体和子实体。我宁愿能够使用脚本自动执行此操作:(

  • 我的问题!!! (终于)

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

    感恩

    谢谢!

    最佳答案

    我不确定您将使用什么过程来定义实体,但是为了使用Doctrine 有效地创建可持久化的实体,例如GenericEngine 和FordEngine,您需要@MappedSuperclass
    http://docs.doctrine-project.org/en/latest/reference/inheritance-mapping.html#mapped-superclasses

    它是抽象类的 Doctrine 等价物。

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

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

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

    关于php - 使用 Symfony 2 CLI 工具,如何为子类生成具有正确类型提示的 getter 和 setter?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18098552/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com