2016-06-17 3 views

ответ

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 не работает таким образом по какой-то причине. Он компилирует сценарий перед каждым исполнением, поэтому он стремится как можно быстрее завершить компиляцию и не прикладывает много усилий для анализа и оптимизации кода.

Update:

Как @deceze указывает на comment, выражение Test::$one не может быть оценена в декларации $two, поскольку он использует класс Test, не полностью определено в этой точке. Даже компиляторы других языков, которые допускают такую ​​ссылку, не могут вычислить значение Test::$one, когда они достигнут объявления $two. Они должны использовать второй проход для компиляции, чтобы иметь возможность оценить его.

+0

Даже после этого 'Test :: $ one' просто недоступен на данный момент, потому что синтаксический анализ определения класса' Test' еще не завершен. – deceze