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

时间:2016-06-17 05:59:44

标签: php class oop object static

private static void LinqToSql()
        {
            DataContext dataContext = new DataContext("data source=.;initial catalog=businessLinqToSql;integrated security=True;MultipleActiveResultSets=True");
            Table<Customer> customers = dataContext.GetTable<Customer>();

            IQueryable<string> query = from c in customers
                                       where c.Name.Length > 5
                                       orderby c.Name.Length
                                       select c.Name.ToUpper();
            foreach (string name in query) Console.WriteLine(name);
        }

为什么会抛出错误,以及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的方式是什么?

1 个答案:

答案 0 :(得分:3)

这是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点。即使是允许此类引用的其他语言的编译器在达到Test::$one的声明时也无法计算$two的值。他们需要使用第二个编译传递来评估它。