【问题标题】:Assigning a static variable to another static variable. Why does it throw an error?将一个静态变量分配给另一个静态变量。为什么会抛出错误?
【发布时间】:2016-10-18 20:30:54
【问题描述】:
Class Test {
   private static $one = ['a','b'];
   private static $two = Test::$one; // Throws an error
   // Error : syntax error, unexpected '$one', expecting 'identifier' or 'class'
}

为什么会抛出错误,这里有什么方法可以使$two = $one

【问题讨论】:

    标签: php class oop object static


    【解决方案1】:

    这是PHP编译器的一个限制,在documentation中有解释:

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

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

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

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

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

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

    更新:

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

    【讨论】:

    • 除此之外,Test::$one 在这一点上根本不可用,因为尚未完成对 Test 类定义的解析。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-15
    • 1970-01-01
    • 2023-03-29
    • 1970-01-01
    • 1970-01-01
    • 2012-11-16
    • 1970-01-01
    相关资源
    最近更新 更多