PHP Использование языковых конструкций в сочетании с магическими методами
Этот question заставлял меня любопытно использовать языковые конструкции в сочетании с магическими методами PHP. Я создал демо-код:
<?php
class Testing {
public function scopeList() {
echo "scopeList";
}
public function __call($method, $parameters) {
if($method == "list") {
$this->scopeList();
}
}
public static function __callStatic($method, $parameters) {
$instance = new static;
call_user_func_array([$instance, $method], $parameters);
}
}
//Testing::list();
$testing = new Testing();
$testing->list();
Почему Testing::list()
выдает синтаксическую ошибку, а $testing->list()
- нет?
Из-за php зарезервированные ключевые слова оба должны потерпеть неудачу?
Ответы
Ответ 1
Обновить PHP 7
PHP 7 обратился к описанному поведению и реализовал функцию, называемую контекстно-зависимым лексером, представленную marcio.
Ваш код будет просто работать с PHP 7.
Ситуация перед PHP 7
Синтаксические ошибки выдаются до того, как PHP даже осознает, что метод доступен через __callStatic()
, это происходит на этапе синтаксического анализа.
Поведение, которое вы описали, кажется ошибкой в парсере PHP, по крайней мере, несоответствие, которое должно быть описано в документации.
Я бы опубликовал отчет об ошибке. Хороший улов!
Обновление: у файла OP есть файл с отчетом об ошибке, который можно найти здесь: https://bugs.php.net/bug.php?id=71157
Ответ 2
Контекстно-зависимые идентификаторы теперь поддерживаются для PHP 7.0 +, и ваш код будет работать. Обновление вашего PHP решит проблему.
Это был одобренный RFC, который внес изменения: https://wiki.php.net/rfc/context_sensitive_lexer.
Вы можете получить дополнительную информацию о новых функциях и об изменениях на следующей (неофициальной) ссылке на PHP 7: https://github.com/tpunt/PHP7-Reference#loosening-reserved-word-restrictions
Ответ 3
По-моему, это потому, что зарезервированные слова,
если вы замените Testing::list();
на call_user_func_array(['Testing', 'list'], []);
, он будет работать как ожидалось.