[Проблема]
Несмотря на предыдущий опыт программирования, новичок в PHP озадачен ошибкой атрибута по умолчанию. Код:
class Foo {
public $path = array(
realpath(".")
);
}
выдает синтаксическую ошибку. Однако следующее работает без проблем:
$path = array(
realpath(".")
);
Возникает вопрос: почему нельзя вызывать функции в атрибутах по умолчанию? Это намеренно или ошибка в реализации?
[Ответ]
Код компилятора PHP указывает на то, что это ограничение является преднамеренным, хотя официального обоснования нет. Надежная реализация этой функциональности создает определенные проблемы, о чем свидетельствуют ограничения в текущей реализации PHP.
Грамматика компилятора определяет объявление переменной класса как:
class_variable_declaration: //... | T_VARIABLE '=' static_scalar //... ;
Поэтому, чтобы присвоить значения переменных, таких как $path, ожидаемое значение должно соответствовать статическому скаляру. Сюда входят массивы со значениями, которые также являются статическими скалярами:
static_scalar: /* compile-time evaluated scalars */ //... | T_ARRAY '(' static_array_pair_list ')' // ... //... ;
Если грамматика допускает следующий синтаксис, который соответствует примеру кода, скрипт обнаружит ошибку «Недопустимый тип привязки»:
class_variable_declaration: //... | T_VARIABLE '=' T_ARRAY '(' array_pair_list ')' // ... ;
Разбор данного примера кода показывает следующие шаги:
zend_do_begin_class_declaration() // Adds an opcode array_init(), zend_do_add_static_array_element() // Do not create new opcodes, add array to class properties zend_do_declare_property() // Declares the property zend_do_early_binding() // Consumes the last opcode and evaluates it
Если код операции не ожидается (например, связанный с функциями или методами), выдается ошибка.
Разрешение нестатических массивов генерирует код операции INIT_ARRAY, который нарушает zend_do_early_binding():
DECLARE_CLASS 'Foo' SEND_VAL '.' DO_FCALL 'realpath' INIT_ARRAY
Чтобы разместить вызовы функций в значениях атрибутов по умолчанию, потребуется новый массив кодов операций, ограниченный объявлением переменной класса, аналогично определениям методов. Однако определение времени такой оценки создает дополнительные проблемы.
Другим динамическим языкам удалось решить эту проблему, но эта функция по-прежнему отсутствует в PHP, возможно, из-за ее сложности и предполагаемого низкого приоритета.
Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.
Copyright© 2022 湘ICP备2022001581号-3