使用PHP 7.2,我有一个使用特征MyClass
的类MyFirstTrait
。它的定义如下:
class MyClass
{
use MyFirstTrait;
}
此MyFirstTrait
使用其他特征MySecondTrait
。它的定义如下:
trait MyFirstTrait
{
use MySecondTrait;
}
MySecondTrait
不使用任何其他特征。它的定义如下:
trait MySecondTrait
{
}
如果我首先定义MyClass
然后定义特征(定义特征的顺序无关紧要),则会引发错误。
该文件将如下:
// Not working
class MyClass { use MyFirstTrait; }
// These two lines can be swapped, the result is the same.
trait MyFirstTrait { use MySecondTrait; }
trait MySecondTrait { }
提出的错误是:
Fatal error: Trait 'MyFirstTrait' not found in …
但是,如果我删除嵌套并从use
中删除MyFirstTrait
子句,则脚本运行时没有错误。如果我首先定义特征然后定义类,也会发生同样的情况。
在第一种情况下,文件看起来像这样:
// Working
class MyClass { use MyFirstTrait; }
trait MyFirstTrait { }
在第二种情况下:
// Working
// These two lines can be swapped, the result is the same.
trait MyFirstTrait { use MySecondTrait; }
trait MySecondTrait { }
class MyClass { use MyFirstTrait; }
为什么在嵌套特征时行为会发生变化?
对我来说没有多大意义,因为在这两种情况下,使用的特征的定义晚于它们的引用。当删除嵌套并且仅使用单个特征时,在定义类之后定义特征没有问题。
答案 0 :(得分:3)
逻辑上,您引用的所有内容都应在引用之前定义。但是有一些例外。退一步,PHP文件分两步解释:
一般来说,类将在 runtime 中定义,这意味着代码按照编写顺序执行。在这里,你必须首先在另一个特征中定义你要去use
的特征。但是,可以生成和定义一些“简单”特征和类解析器中的解析器,因此它们将在运行时之前可用。这纯粹是一种性能优化。
由于解析器的功能可能会从一个版本扩展到另一个版本(例如,在某些时候简单算术),因此PHP认为“简单类/特征”不是我必须尝试记住或依赖的东西。表达式变得支持像static $foo = 4 + 2;
之类的语句,这在以前是一个解析错误。)