【发布时间】:2013-04-30 00:08:45
【问题描述】:
首先,这篇文章有点长,谢谢阅读。
我的问题与此类似: Class not found in the same file
我有一个最初在 2008 年为 PHP 5 编写的定制框架,多年来它已经升级为与 PHP 5.3 一起使用。我一直在研究 5.4 的兼容性并遇到了一个严重的问题。
ORM 层自动为每个 DB 表生成类。这些类都位于每个表的一个文件中,我们的自动加载器会在需要时加载该文件。 例如,“公共”模式(postgresql)中的“客户”表将具有以下类: PublicCustomer、PublicCustomerDBReader、PublicCustomerDBWriter。 现在这可能不是理想的设置,但它是我们目前拥有的。
在 PHP 5.3 中,如果需要 PublicCustomer,则该文件将被包含、解析,并且所有上述类都将可用。因此,例如,如果在 PublicCustomer 上调用了一个静态方法,并且该方法调用了 PublicCustomerDBReader 中的某些内容,那将可以正常工作,因为该类在同一个文件中。
在 PHP 5.4 中,似乎在核心中进行了一些优化。在上述场景中:
在 PublicCustomer 中调用了一个静态方法。
自动加载器找到并加载正确的文件。
PHP 解析器只解析到它需要的地方; PublicCustomer 类。它没有解析或实例化 PublicCustomerDBReader 类。我可以通过测试该类是否存在并查看解析器在被包含时是否到达文件末尾、在调用方法时(它没有)来确认这一点。
- PublicCustomer 中的方法然后尝试调用 PublicCustomerDBReader 中的方法。这失败了,因为我们的自动加载器已经需要该文件一次。
在我看来,我有两个解决方案:
- 将这些类分开,这样每个类都有一个文件(这会产生大量文件)
- 重新设计 ORM 层,不再需要多个类。
我是否正确理解了上述问题?
有谁知道是否在 PHP 5.4 中进行了会导致这种行为的优化或更改?
还有其他我没有考虑过的问题的潜在解决方案吗?
【问题讨论】:
-
你应该使用方法1。你有多少个类?这不应该是很多工作。 PHP 自动加载器基于与类名\命名空间相关的文件名\目录。 PHP 中没有内置的包支持。无论如何,它应该使您的脚本更加模块化。为什么只需要 class2 时应用必须解析 class1 和 class2?
-
是否有任何东西阻止您以为每个类创建单独文件的方式修改 ORM?这应该很容易解决问题,并且无论如何都会更好。 ;)
-
我可以将类分成单独的文件,但这显然会增加 ORM 中的文件数量。每个 DB 表实际上有 5 个类,因此这会将文件数量增加五倍。我管理的一些数据库有 300-400 个表,这意味着大约 2000 个文件。显然这不是一个伟大的设计,我只是想知道如何最好地改变它。
-
自己无法重现。你能准备最少的代码来重现它的行为吗?
-
也无法重现,也找不到其他关于严重破坏功能的报告。正如 sectus 所说,你能重现一个简单的例子吗?
标签: php