Почему пустой ожидает T_PAAMAYIM_NEKUDOTAYIM, когда задана не переменная?

<?php define('foo', 'bar'); if (empty(foo)) { echo 'qux'; } 

http://codepad.org/G1TSK1c6
Ошибка анализа: синтаксическая ошибка, неожиданный ')', ожидающий T_PAAMAYIM_NEKUDOTAYIM в строке 4

Я знаю, что empty() только позволяет передавать переменные в качестве аргумента, но почему он ожидает T_PAAMAYIM_NEKUDOTAYIM (т.е. :: :), когда я даю ему константу?

Следующей логической задачей, которую хочет парсер, является :: поскольку foo не является переменной.

 if (empty(foo::$bar)) { } 

Единственное, что работает, когда empty() не передается переменной. Ваш пример оценивается как empty(bar) где парсер предполагает, что bar является именем класса, и теперь ожидает статическую переменную-член.

Видел это, делая некоторые исследования, хотя я знаю, что это удар, я думал, что я лучше это разъясню.

empty() не является функцией, а конструкцией языка. Это означает, что код синтаксического анализа, лежащий в основе, отличается от кода анализа аргументов, присланных обычным функциям или методам. Это может показаться непоследовательным вначале, когда вы испытываете сообщения об ошибках, подобные этому, но немного сократите его.

empty() ожидает проверить что-то переменное; константа не является переменной, поэтому она не включена в список возможных синтаксисов, которые могут быть переданы этой конструкции, что имеет смысл, поскольку в противном случае вы делали бы что-то нелогичное (проверяя пустоту в постоянном значении).

Единственными другими возможными переменными, которые мы имеем в PHP, являются старые старые переменные и свойства класса, поскольку они взаимозаменяемы, соответствующие синтаксисы могут быть представлены следующим образом:

 <name> ::= [a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]* <variable> ::= $ <name> <property> ::= <name> :: <name> || $ <name> :: <name> || $ <name> -\> <name> 

Это означает, что если вы передаете константу, PHP будет читать это как имя класса и, следовательно, ожидает двойной токен двоеточия « :: », следовательно, почему ошибка имеет смысл.

Надеюсь, это было несколько проницательно 😉

Я посмотрел на это, попробовал это на моей локальной установке PHP и угадал, что? Он работал без сбоев (PHP 5.5.6). Попробовав тот же код в разных версиях PHP, я обнаружил, что он не работает во всех версиях PHP <5.5.x и работает иначе.

Итак, я взял на себя документацию PHP, точнее ее журнал изменений с 5.4.x до 5.5.x и нашел следующее:

http://www.php.net/manual/en/migration55.new-features.php#migration55.new-features.empty

empty () поддерживает произвольные выражения

Теперь поддерживается произвольное выражение вместо переменной в empty (). Например:

 if (empty(TRUE)) { echo "This will NOT be printed.\n"; } if (empty(FALSE)) { echo "This will be printed.\n"; } 

Вышеприведенный пример выводит:

Это будет напечатано.

Поэтому, если вы используете PHP> = 5.5.x, это не будет проблемой.

Вы можете протестировать код на разных версиях PHP, используя эту службу: http://sandbox.onlinephpfunctions.com/ . Я не мог, по моей жизни, выяснить, как сохранить образцы кода (я всегда не получал капчу, хотя он прост – я думаю, что что-то МОЖЕТ быть разбито на их конце).

empty() ожидает переменные, а не константы. Вы должны использовать defined() для констант.

Просто, хотя, но я думаю, что эта ошибка возникает при разборе кода.

foo , не является переменной или строкой, поэтому в контексте синтаксического анализа следующее решение может быть атрибутом класса., но это не потому, что нет :: , но это должно быть потому, что константы не должны использоваться здесь , и он остается атрибутом класса или методом.