单个文件中 PHP class 扩展名的顺序
Order of PHP class extensions in a single file
在某些情况下,乱序定义 PHP class 扩展会导致致命错误,而在某些情况下则不会。我正在尝试了解潜在的行为。
例如,两者
<?php
class BaseClass {}
class FirstExt extends BaseClass {}
和
<?php
class FirstExt extends BaseClass {}
class BaseClass {}
很好,所以简单地定义子class乱序不会导致问题。
但是,当涉及三个 classes 时,会出现错误,但 仅在一种特定情况下 ,即 classes 的链是以相反的顺序定义。也就是说,以下代码会导致致命错误:
<?php
class SecondExt extends FirstExt {}
class FirstExt extends BaseClass {}
class BaseClass {}
如果你尝试从命令行运行这个(比如main.php
),你会得到
PHP Fatal error: Class 'FirstExt' not found in /path/to/main.php on line 2
然而,三个 classes 运行 的其他五个排序中的任何一个都没有错误。我很惊讶甚至
<?php
class SecondExt extends FirstExt {}
class BaseClass {}
class FirstExt extends BaseClass {}
工作正常。区别因素是在给出错误的情况下,所有三对可能的 classes 都是乱序的,而在所有其他情况下,三对中最多有两对是乱序的。
产生这种行为的幕后原因是什么?
行为不直观,但我不认为这是错误,这只是 PHP 加载 classes 的方式的结果。
为了让 class 扩展父 class,必须在定义子 class 时定义父 class。
根据我的观察,似乎在解析文件并开始执行后,定义了以下 classes:
- 内置classes
- 所有用户定义的class在文件被解析之前定义的
- 用户定义的基础class在该文件中
- 该文件中的用户定义 class 扩展另一个 class 已经定义的,在该文件的前面或在该文件被解析之前
基本上任何可以在编译时定义的 class 都会被定义,而任何其他在那个时候没有定义的 class 将(试图被)定义在 运行时间.
所以在这个例子中:
<?php
echo class_exists('A') ? "Yes" : "No"; // No
echo class_exists('B') ? "Yes" : "No"; // Yes
echo class_exists('C') ? "Yes" : "No"; // Yes
class A extends B {}
class C {}
class B extends C {}
classB是在classA试图扩展它的时候定义的,因为它是在解析文件时定义的,因为在文件中classC是在它之前定义的。
但在这个例子中:
<?php
echo class_exists('A') ? "Yes" : "No"; // No
echo class_exists('B') ? "Yes" : "No"; // No
echo class_exists('C') ? "Yes" : "No"; // Yes
class A extends B {}
class B extends C {}
class C {}
class B is not defined when class A tries to extend it, because it was not defined when the file was parsed, 因为class C was not defined before it in文件。
PHP 试图找到它,但它不会再次签入同一个文件,它会尝试自动加载它。那是你得到 "not found".
的时候
添加第四个 class,您可以看到它不仅发生在 classes 以相反顺序定义时:
echo class_exists('A') ? "Yes" : "No"; // No
echo class_exists('B') ? "Yes" : "No"; // No
echo class_exists('C') ? "Yes" : "No"; // Yes
echo class_exists('D') ? "Yes" : "No"; // Yes
class A extends B {}
class D {}
class B extends C {}
class C extends D {}
在某些情况下,乱序定义 PHP class 扩展会导致致命错误,而在某些情况下则不会。我正在尝试了解潜在的行为。
例如,两者
<?php
class BaseClass {}
class FirstExt extends BaseClass {}
和
<?php
class FirstExt extends BaseClass {}
class BaseClass {}
很好,所以简单地定义子class乱序不会导致问题。
但是,当涉及三个 classes 时,会出现错误,但 仅在一种特定情况下 ,即 classes 的链是以相反的顺序定义。也就是说,以下代码会导致致命错误:
<?php
class SecondExt extends FirstExt {}
class FirstExt extends BaseClass {}
class BaseClass {}
如果你尝试从命令行运行这个(比如main.php
),你会得到
PHP Fatal error: Class 'FirstExt' not found in /path/to/main.php on line 2
然而,三个 classes 运行 的其他五个排序中的任何一个都没有错误。我很惊讶甚至
<?php
class SecondExt extends FirstExt {}
class BaseClass {}
class FirstExt extends BaseClass {}
工作正常。区别因素是在给出错误的情况下,所有三对可能的 classes 都是乱序的,而在所有其他情况下,三对中最多有两对是乱序的。
产生这种行为的幕后原因是什么?
行为不直观,但我不认为这是错误,这只是 PHP 加载 classes 的方式的结果。
为了让 class 扩展父 class,必须在定义子 class 时定义父 class。
根据我的观察,似乎在解析文件并开始执行后,定义了以下 classes:
- 内置classes
- 所有用户定义的class在文件被解析之前定义的
- 用户定义的基础class在该文件中
- 该文件中的用户定义 class 扩展另一个 class 已经定义的,在该文件的前面或在该文件被解析之前
基本上任何可以在编译时定义的 class 都会被定义,而任何其他在那个时候没有定义的 class 将(试图被)定义在 运行时间.
所以在这个例子中:
<?php
echo class_exists('A') ? "Yes" : "No"; // No
echo class_exists('B') ? "Yes" : "No"; // Yes
echo class_exists('C') ? "Yes" : "No"; // Yes
class A extends B {}
class C {}
class B extends C {}
classB是在classA试图扩展它的时候定义的,因为它是在解析文件时定义的,因为在文件中classC是在它之前定义的。
但在这个例子中:
<?php
echo class_exists('A') ? "Yes" : "No"; // No
echo class_exists('B') ? "Yes" : "No"; // No
echo class_exists('C') ? "Yes" : "No"; // Yes
class A extends B {}
class B extends C {}
class C {}
class B is not defined when class A tries to extend it, because it was not defined when the file was parsed, 因为class C was not defined before it in文件。
PHP 试图找到它,但它不会再次签入同一个文件,它会尝试自动加载它。那是你得到 "not found".
的时候添加第四个 class,您可以看到它不仅发生在 classes 以相反顺序定义时:
echo class_exists('A') ? "Yes" : "No"; // No
echo class_exists('B') ? "Yes" : "No"; // No
echo class_exists('C') ? "Yes" : "No"; // Yes
echo class_exists('D') ? "Yes" : "No"; // Yes
class A extends B {}
class D {}
class B extends C {}
class C extends D {}