将静态变量分配给另一个静态变量.为什么会抛出错误?

Suh*_*pta 5 php oop static class object

Class Test {
   private static $one = ['a','b'];
   private static $two = Test::$one; // Throws an error
   // Error : syntax error, unexpected '$one', expecting 'identifier' or 'class'
}
Run Code Online (Sandbox Code Playgroud)

为什么会抛出错误,这里的方式是什么$two= $one

axi*_*iac 3

这是 PHP 编译器的限制,文档中对此进行了解释:

与任何其他 PHP 静态变量一样,静态属性在 PHP 5.6 之前只能使用文字或常量进行初始化;不允许使用表达式。在 PHP 5.6 及更高版本中,相同的规则适用于 const 表达式:一些有限的表达式是可能的,只要它们可以在编译时计算。

这里的关键语句是:“只要它们可以在编译时评估”

从您收到的错误消息中我可以看出您正在使用 PHP 5。在 PHP 7 上,错误消息被重新措辞以清楚地说明问题。它说“常量表达式包含无效操作”

第一个静态变量 ( ) 的声明$one可以编译,因为您使用常量表达式对其进行初始化。['a','b']是一个字符串数组,可以在编译时对其进行求值,一切都很好。

第二个静态变量 ( $two) 使用非常量表达式 ( Test::$one) 进行初始化。Test::$one是一个变量。您可以看出,其值初始值在编译时已知(请参阅上面的段落),并且可以在编译时计算表达式。

这种行为需要在编译时对代码进行更深入的分析。它可能是在 C++ 或 Java 编译器中实现的,但这些语言只编译一次,它们生成的代码存储在文件中,稍后执行或解释。PHP 编译器不以这种方式工作是有原因的。它在每次执行之前都会编译脚本,这就是为什么它的目标是尽快完成编译,而不会在代码分析和优化上花费太多精力。

更新:

正如 @deceze 在注释中指定的那样,Test::$one无法在 的 声明中计算表达式,因为它使用此时尚未完全定义的$two类。即使允许这种引用的其他语言的编译器也无法计算到达 的声明时Test的值。他们需要使用第二次编译才能对其进行评估。Test::$one$two