【问题标题】:PHP class definition orderPHP 类定义顺序
【发布时间】:2017-09-16 06:56:38
【问题描述】:

我有一个使用 classpreloader 和一些自定义代码创建的文件,这些代码将一堆类文件压缩成一个文件以进行分发:

https://raw.githubusercontent.com/jnvsor/kint/1efd147f9831ade2e03921f7111ced07428556ab/build/kint.php

根据 travis 的说法,除了夜间之外,这一切都失败了,并出现错误:

致命错误:第 315 行 /home/travis/build/jnvsor/kint/build/kint.php 中的未知类 Kint_Renderer_Text

正如您在第 315 行看到的那样,class Kint_Renderer_Plain extends Kint_Renderer_Text 在文件后面的第 418 行使用class Kint_Renderer_Text extends Kint_Renderer 定义。

人们会假设这意味着单个文件中的类顺序很重要。

但是当我在构建发布文件之前sort()源文件时,travis 说一切都很顺利,尽管新文件也有类似的情况:

https://raw.githubusercontent.com/jnvsor/kint/1a657f06cd693b3f9db8f9458f900ef7bb378b53/build/kint.php

例如,class Kint_Object_Closure extends Kint_Object_Instance 在第 1249 行,class Kint_Object_Instance extends Kint_Object 在第 1352 行

那么问题就变成了:PHP 中类的排序要求到底是什么?

【问题讨论】:

  • 据我所知,您的第一个 PHP 文件在 class Kint_Renderer_Text extends Kint_Renderer 之前有 class Kint_Renderer_Plain extends Kint_Renderer_Text,而您的第二个 PHP 文件在 class Kint_Object_Closure extends Kint_Object_Instance 之前有 class Kint_Object_Instance extends Kint_Object。所以看起来第二个文件中的顺序确实发生了变化。话虽如此,请参阅stackoverflow.com/questions/8337286/… 以获得更好的解释。长话短说,是的,顺序确实很重要。
  • 不,第二个在Kint_Object_Instance 定义之前有Kint_Object_Closure 定义。这就是为什么它很奇怪。而且那里没有接口,所以它不能与那个问题重复..
  • “将一堆类文件压缩成一个文件进行分发” 不要重新发明轮子,使用phar

标签: php


【解决方案1】:

PHP 中类的排序要求究竟是什么

类必须存在才能扩展。因此,如果类 A 扩展类 BBA 的实例化时刻未知,您的代码将失败。您可以使用autoloader 来解决这个问题,但它会破坏将所有内容保存在一个文件中的目的(无论如何这是错误的想法)。

【讨论】:

    【解决方案2】:

    我又一次回答了我自己的问题,因为 SO 上没有人会费心阅读超过 10 秒...

    原来 PHP 只检查同一文件中的依赖关系一次,而不是递归检查,然后无法更新错误消息。结果你会得到这样的结果:

    <?php
    class A extends B {} // boom: <b>Fatal error</b>:  Class 'B' not found...
    class B extends C {}
    class C {}
    

    在重新排序依赖项依赖项时可以正常工作:

    <?php
    class A extends B {}
    class C {}
    class B extends C {}
    

    这与超过 2 个扩展的行为相同。如果是第 3 个类找不到它的扩展,它仍然会报告找不到第二个类:

    <?php
    class A extends B {} // boom: <b>Fatal error</b>:  Class 'B' not found...
    class C extends D {}
    class B extends C {}
    class D {}
    

    这已在 7.2(仍为预发布版本)中得到修复,它将递归检查,或者至少检查更深入 - 因为正如我在问题中提到的,此错误不会在夜间发生。

    【讨论】:

      猜你喜欢
      • 2011-03-28
      • 1970-01-01
      • 2013-06-22
      • 2011-09-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-28
      相关资源
      最近更新 更多