Все сталкиваются с синтаксическими ошибками. Даже опытные программисты делают опечатки. Для новичков это всего лишь часть учебного процесса. Однако часто легко интерпретировать сообщения об ошибках, такие как:
Ошибка синтаксического анализа PHP: синтаксическая ошибка, неожиданное '{' в index.php в строке 20
Неожиданный символ не всегда настоящий преступник. Но номер строки дает приблизительное представление о том, с чего начать.
Всегда смотрите на контекст кода. Синтаксическая ошибка часто скрывается в упомянутых или в предыдущих строках кода. Сравните ваш код с примерами синтаксиса из руководства.
Хотя не каждый случай соответствует другому. Тем не менее, есть некоторые общие шаги для решения синтаксических ошибок. Эти ссылки суммировали общие подводные камни:
Неожиданный T_CONSTANT_ENCAPSED_STRING
Неожиданный T_ENCAPSED_AND_WHITESPACE
Неожиданный T_IF
Неожиданный T_FOREACH
Неожиданный T_FOR
Неожиданный T_WHILE
Неожиданный T_DO
Неожиданный T_PRINT
Неожиданный T_ECHO
Неожиданное продолжение (T_CONTINUE)
Неожиданное продолжение (T_BREAK)
Неожиданное продолжение (T_RETURN)
Неожиданный T_IS_EQUAL
Неожиданный T_IS_GREATER_OR_EQUAL
Неожиданный T_IS_IDENTICAL
Неожиданный T_IS_NOT_EQUAL
Неожиданный T_IS_NOT_IDENTICAL
Неожиданный T_IS_SMALLER_OR_EQUAL
Неожиданный <
Неожиданный >
Неожиданный символ на входе: ' \
' (ASCII = 92) состояние = 1
Неожиданная публика (T_PUBLIC)
Неожиданный "приват" (T_PRIVATE)
Неожиданный "защищенный" (T_PROTECTED)
Неожиданный финал (T_FINAL) …
Неожиданно ,
(запятая)
Не ожидал .
(Период)
Неожиданно ;
(точка с запятой)
Неожиданный *
(звездочка)
Неожиданный :
(двоеточие)
Тесно связанные ссылки:
""
умные '
цитаты ничего не значат для PHPА также:
Хотя Qaru также приветствует начинающих программистов, он в основном нацелен на вопросы профессионального программирования.
Если ваш браузер отображает сообщения об ошибках, такие как "SyntaxError: недопустимый символ", то это на самом деле не php -related, а javascript - синтаксическая ошибка.
Синтаксические ошибки, возникающие в коде поставщика. Наконец, учтите, что если синтаксическая ошибка возникла не при редактировании базы кода, а после установки или обновления пакета внешнего поставщика, это может быть связано с несовместимостью версии PHP, поэтому проверьте требования поставщика к настройке платформы.,
PHP относится к С-стилю и императивным языкам программирования. У него есть жесткие правила грамматики, которые он не может восстановить при обнаружении неулокальных символов или идентификаторов. Это не может угадать ваши намерения кодирования.
Есть несколько основных мер предосторожности, которые вы всегда можете предпринять:
Используйте правильные отступы кода или используйте любой высокий стиль кодирования. Читаемость предотвращает неровности.
Используйте IDE или редактор для PHP с подсветкой синтаксиса. Что также помогает с скобками/балансировкой скобок.
Прочитайте справочник по языку и примеры в руководстве. Дважды, чтобы стать несколько опытным.
Типичное сообщение об ошибке синтаксиса гласит:
Ошибка разбора: синтаксическая ошибка, неожиданный T_STRING, ожидающий '
;
' в file.php в строке 217
Который перечисляет возможное местоположение синтаксической ошибки. Смотрите упомянутое имя файла и номер строки.
Прозвище, такие как T_STRING
объясняет, какой символ анализатор/токенизатор не удалось обработать, наконец. Однако это не обязательно является причиной синтаксической ошибки.
Важно также рассмотреть предыдущие строки кода. Часто синтаксические ошибки - это просто неудачи, случившиеся ранее. Номер строки ошибки - именно то, где анализатор окончательно отказался от обработки всего этого.
Есть много подходов, чтобы сузить и исправить синтаксические ошибки.
Откройте указанный исходный файл. Посмотрите на упомянутую строку кода.
Для убегающих строк и неулокальных операторов, это обычно, где вы найдете виновника.
Прочитайте строку слева направо и представьте, что делает каждый символ.
Более регулярно вы должны смотреть и на предыдущие строки.
В частности, отсутствует ;
точки с запятой отсутствуют в конце предыдущей строки/оператора. (По крайней мере, со стилистической точки зрения.)
Если {
кодовые блоки }
неправильно закрыты или вложены, вам может потребоваться еще больше изучить исходный код. Используйте правильный отступ кода, чтобы упростить это.
Посмотрите на цвет синтаксиса !
Строки, переменные и константы должны иметь разные цвета.
Операторы +-*/.
также должен быть отчетливо окрашен. В противном случае они могут быть в неправильном контексте.
Если вы видите, что раскрашивание строк распространяется слишком далеко или слишком коротко, значит, вы обнаружили неэкранированный или отсутствующий закрывающий "
или '
маркер строки.
Наличие двух одинаковых знаков препинания рядом друг с другом также может означать проблемы. Обычно операторы являются одинокими, если это не ++
, --
или круглые скобки после оператора. Две строки/идентификаторы, непосредственно следующие друг за другом, являются неверными в большинстве контекстов.
Пробел - твой друг. Следуйте любому стилю кодирования.
Временно разбить длинные очереди.
Вы можете свободно добавлять символы новой строки между операторами или константами и строками. Затем синтаксический анализатор конкретизирует номер строки для анализа ошибок. Вместо того, чтобы смотреть на очень длинный код, вы можете изолировать отсутствующий или неулокальный синтаксический символ.
Разделите сложные операторы if
на отдельные или вложенные условия if
.
Вместо длинных математических формул или логических цепочек используйте временные переменные для упрощения кода. (Более читабельно = меньше ошибок.)
Добавьте новые строки между:
Разделение длинных блоков кода действительно помогает определить источник синтаксических ошибок.
Закомментируйте оскорбительный код.
Если вы не можете изолировать источник проблемы, начните закомментировать (и, следовательно, временно удалить) блоки кода.
Как только вы избавились от ошибки синтаксического анализа, вы нашли источник проблемы. Посмотри внимательнее там.
Иногда вы хотите временно удалить завершенные функциональные/методические блоки. (В случае непревзойденных фигурных скобок и ошибочно с отступом кода.)
Если вы не можете решить проблему с синтаксисом, попробуйте переписать закомментированные разделы с нуля.
Как новичок, избегайте некоторых запутанных синтаксических конструкций.
Троичный ? :
? :
оператор условия может компактировать код и действительно полезен. Но это не помогает удобочитаемости во всех случаях. Предпочитаю простые операторы if
пока они не обращены.
Альтернативный синтаксис PHP (if:
/elseif:
/endif;
) является общим для шаблонов, но, возможно, менее прост для понимания, чем обычные блоки {
code }
.
Наиболее распространенные ошибки новичка:
Пропущенные точки с запятой ;
для завершения операторов/строк.
Несоответствующие строковые кавычки для "
или '
и неэкранированные кавычки внутри.
Забытые операторы, в частности для строки .
конкатенации.
Несбалансированный (
скобки )
. Подсчитайте их в сообщенной строке. Есть ли их равное количество?
Не забывайте, что решение одной синтаксической проблемы может раскрыть следующую.
Если вы решите одну проблему, но в следующем коде появится другая, вы в основном на правильном пути.
Если после редактирования новой синтаксической ошибки появляется в той же строке, то ваша попытка изменения была неудачной. (Не всегда, хотя.)
Восстановите резервную копию ранее работающего кода, если вы не можете это исправить.
diff
в сломанной и последней рабочей версии. Что может быть полезным для понимания проблемы синтаксиса. Невидимые блуждающие символы Юникода: в некоторых случаях вам нужно использовать hexeditor или другой редактор/просмотрщик в вашем источнике. Некоторые проблемы не могут быть найдены только при просмотре вашего кода.
Попробуйте grep --color -P -n "\[\x80-\xFF\]" file.php
в качестве первой меры, чтобы найти не-ASCII символы.
В частности, спецификации, пробелы нулевой ширины или неразрывные пробелы и регулярные умные кавычки могут найти свой путь в исходный код.
Позаботьтесь о том, какой тип переносов строк сохраняется в файлах.
PHP только чтит \n переводы строк, а не \r возврат каретки.
Что иногда является проблемой для пользователей MacOS (даже в OS X для неправильно настроенных редакторов).
Часто проблема возникает только при использовании однострочных комментариев //
или #
. Многострочные комментарии /*...*/
редко мешают анализатору, когда /*...*/
игнорируются.
Если ваша синтаксическая ошибка не передается через Интернет: бывает, что на вашем компьютере есть синтаксическая ошибка. Но размещение того же самого файла в Интернете больше не демонстрирует его. Что может означать только одну из двух вещей:
Вы смотрите не на тот файл!
Или ваш код содержал невидимый блуждающий Unicode (см. Выше). Вы можете легко узнать: просто скопируйте свой код обратно из веб-формы в текстовый редактор.
Проверьте свою версию PHP. Не все синтаксические конструкции доступны на каждом сервере.
php -v
для интерпретатора командной строки
<?php phpinfo();
за тот, который вызывается через веб-сервер.
Это не обязательно то же самое. В частности, при работе с фреймворками вы будете их сопоставлять.
Не используйте зарезервированные ключевые слова PHP в качестве идентификаторов для функций/методов, классов или констант.
Метод проб и ошибок - ваше последнее средство.
Если ничего не помогает, вы всегда можете погуглить ваше сообщение об ошибке. Синтаксические символы не так легко найти (хотя переполнение стека индексируется SymbolHound). Поэтому может потребоваться просмотреть еще несколько страниц, прежде чем вы найдете что-то актуальное.
Дальнейшие руководства:
Если ваш сайт просто пустой, то причиной обычно является синтаксическая ошибка. Включить их отображение с помощью:
error_reporting = E_ALL
display_errors = 1
В вашем php.ini
вообще, или через .htaccess
для mod_php, или даже .user.ini
с настройками FastCGI.
Включение этого в сломанном скрипте слишком поздно, потому что PHP не может даже интерпретировать/запустить первую строку. Быстрый обходной путь - создание сценария-оболочки, скажем test.php
:
<?php
error_reporting(E_ALL);
ini_set("display_errors", 1);
include("./broken-script.php");
Затем вызовите ошибочный код, обратившись к этому сценарию оболочки.
Это также помогает включить PHP error_log
и заглянуть в ваш error.log
веб-сервера, когда сценарий дает сбой с ответами HTTP 500.
error_reporting(E_ALL | E_STRICT);
для более ранних версий PHP
Я думаю, что эта тема полностью перегружена/сложна. Использование IDE - это способ избежать ошибок синтаксиса. Я бы даже сказал, что работа без IDE является непрофессиональной. Зачем? Поскольку современные IDE проверяют ваш синтаксис после каждого вводимого вами символа. Когда вы кодируете, и вся ваша строка становится красной, и большое предупреждение показывает вам точный тип и точное положение синтаксической ошибки, тогда абсолютно нет необходимости искать другое решение.
Вы (эффективно) никогда не столкнетесь с синтаксическими ошибками снова, просто потому, что видите их правильно по мере ввода. Шутки в сторону.
Отличные IDE с проверкой синтаксиса (все они доступны для Linux, Windows и Mac):
[
В эти дни, неожиданная [
скобка массива обычно рассматриваются на устаревшие версии PHP. Синтаксис короткого массива доступен начиная с PHP > = 5.4. Более старые установки поддерживают только array()
.
$php53 = array(1, 2, 3);
$php54 = [1, 2, 3];
⇑
Разыменование результата функции массива также недоступно для более старых версий PHP:
$result = get_whatever()["key"];
⇑
Справка - Что означает эта ошибка в PHP? - "Синтаксическая ошибка, неожиданная \[
" показывает наиболее распространенные и практические обходные пути.
Тем не менее, вам всегда лучше просто обновить установку PHP. Для общих планов SetHandler php56-fcgi
можно ли использовать SetHandler php56-fcgi
, чтобы включить более новую среду выполнения.
Смотрите также:
Кстати, есть также препроцессоры и преобразователи синтаксиса PHP 5.4, если вы действительно цепляетесь за более старые + более медленные версии PHP.
Другие причины для неожиданного [
синтаксические ошибки
Если это не несоответствие версии PHP, то это часто простая синтаксическая ошибка или ошибка синтаксиса новичка:
Вы не можете использовать объявления/выражения свойств массива в классах, даже в PHP 7.
protected $var["x"] = "Nope";
⇑
Путать [
с открывающимися фигурными скобками {
или круглыми скобками (
это распространенный недосмотр).
foreach [$a as $b)
⇑
Или даже:
function foobar[$a, $b, $c] {
⇑
Или пытаться разыменовать константы (до PHP 5.6) как массивы:
$var = const[123];
⇑
По крайней мере, PHP интерпретирует это const
как постоянное имя.
Если вы хотели получить доступ к переменной массива (что является типичной причиной здесь), то добавьте начальный $
sigil - так он станет $varname
.
Вы пытаетесь использовать ключевое слово global
для члена ассоциативного массива. Это неверный синтаксис:
global $var['key'];
]
закрывающая квадратная скобка Это несколько реже, но есть также синтаксические аварии с завершающим массивом ]
скобка.
Опять несоответствие с )
круглые скобки или }
фигурные скобки являются общими:
function foobar($a, $b, $c] {
⇑
Или пытаться завершить массив, где его нет:
$var = 2];
Что часто происходит в объявлениях многострочных и вложенных массивов.
$array = [1,[2,3],4,[5,6[7,[8],[9,10]],11],12]],15];
⇑
Если да, то использовать IDE для согласования кронштейна, чтобы найти преждевременное ]
закрытие массива. По крайней мере, используйте больше пробелов и новых строк, чтобы сузить его.
"Неожиданное T_VARIABLE
" означает, что существует буквальное имя $variable
, которое не вписывается в текущую структуру выражения/оператора.
Это чаще всего указывает на отсутствующую точку с запятой в предыдущей строке. Переменные присваивания, следующие за выражением, являются хорошим показателем, на который следует обратить внимание:
⇓
func1()
$var = 1 + 2; # parse error in line +2
Частые неудачи - это конкатенации строк с забытыми .
оператор:
⇓
print "Here comes the value: " $value;
Кстати, вы должны предпочесть строчную интерполяцию (базовые переменные в двойных кавычках), когда это помогает читаемости. Это позволяет избежать этих синтаксических проблем.
Строковая интерполяция - это основная функция языка сценариев. Не стыдно использовать его. Игнорируйте любую рекомендацию по микрооптимизации относительно переменной
.
ускорение конкатенации. Не это.
Конечно, одна и та же проблема может возникнуть в других выражениях, например арифметических операций:
⇓
print 4 + 7 $var;
PHP не может угадать здесь, если переменная должна быть добавлена, вычтена или сравнена и т.д.
То же самое для списков синтаксиса, например, в массивах, где парсер также указывает ожидаемую запятую ,
например:
⇓
$var = array("1" => $val, $val2, $val3 $val4);
Или списки параметров функций:
⇓
function myfunc($param1, $param2 $param3, $param4)
Эквивалентно вы видите это со list
или global
утверждениями или при отсутствии ;
точка с запятой в цикле for
.
Эта ошибка парсера также встречается в объявлениях классов. Вы можете назначать только статические константы, а не выражения. Таким образом, парсер жалуется на переменные в качестве назначенных данных:
class xyz { ⇓
var $value = $_GET["input"];
Непревзойденные }
закрывающиеся фигурные скобки могут, в частности, привести сюда. Если метод заканчивается слишком рано (используйте правильный отступ!), Тогда блуждающая переменная обычно неправильно помещается в тело объявления класса.
Вы также можете никогда не иметь переменную, следуя за идентификатором напрямую:
⇓
$this->myFunc$VAR();
Кстати, это распространенный пример, когда, возможно, предполагалось использовать переменные переменные. В этом случае поиск свойства переменной с помощью $this->{"myFunc$VAR"}();
например.
Имейте в виду, что использование переменных переменных должно быть исключением. Новички часто пытаются использовать их слишком случайно, даже когда массивы будут проще и более уместны.
Скорейшее типирование может привести к забытой открывающей скобке для операторов if
и for
и foreach
:
⇓
foreach $array as $key) {
Решение: добавьте недостающее открытие (
между оператором и переменной.
⇓
else ($var >= 0)
Решение. Удалите условия из else
или используйте elseif
.
⇓
function() uses $var {}
Решение. Добавьте скобки вокруг $var
.
Как упоминалось в справочном ответе "Невидимый бездомный Юникод" (например, неразрывное пространство), вы также можете увидеть эту ошибку для ничего не подозревающего кода:
<?php
⇐
$var = new PDO(...);
Это довольно распространено в начале файлов и для копирования и вставки кода. Проверьте с помощью шестнадцатеричного кода, если ваш код визуально не содержит синтаксическую проблему.
T_CONSTANT_ENCAPSED_STRING
имена T_CONSTANT_ENCAPSED_STRING
и T_ENCAPSED_AND_WHITESPACE
относятся к цитированным "string"
литералам.
Они используются в разных контекстах, но проблема синтаксиса весьма схожа. T_ENCAPSED... предупреждения встречаются в контексте с двойной кавычкой строки, в то время как T_CONSTANT... строки часто сбиваются с помощью простых выражений или утверждений PHP.
И это чаще всего встречается при некорректной интерполяции переменных PHP:
⇓ ⇓
echo "Here comes a $wrong['array'] access";
Цитирование ключей массивов является обязательным в контексте PHP. Но в двойных кавычках (или HEREDOC) это ошибка. Парсер жалуется на содержащуюся в одиночном кавычке 'string'
, потому что обычно он ожидает там литерального идентификатора/ключа.
Точнее, это справедливо для использования простого синтаксиса в стиле PHP2 в двойных кавычках для ссылок на массивы:
echo "This is only $valid[here] ...";
Вложенные массивы или более глубокие ссылки на объекты, однако, требуют синтаксиса сложного фигурного синтаксиса:
echo "Use {$array['as_usual']} with curly syntax.";
Если вы не уверены, это обычно безопаснее использовать. Он часто даже считается более читаемым. И лучшие IDE на самом деле используют для этого разную синтаксическую раскраску.
Если строка следует за выражением, но не имеет конкатенации или другого оператора, то вы увидите, что PHP жалуется на строковый литерал:
⇓
print "Hello " . WORLD " !";
Хотя это очевидно для вас и меня, PHP просто не может догадаться, что строка должна быть добавлена туда.
Такая же синтаксическая ошибка возникает при смешивании строковых разделителей. Строка запускается один '
или двойной "
цитаты и заканчивается тем же.
⇓
print "<a href="' . $link . '">click here</a>";
⌞⎽⎽⎽⎽⎽⎽⎽⎽⌟⌞⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⌟⌞⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⌟
Этот пример начинался с двойных кавычек. Но двойные кавычки также предназначались для атрибутов HTML. Предполагаемый оператор конкатенации внутри, однако, интерпретировался как часть второй строки в одинарных кавычках.
Совет. Установите редактор /IDE для использования слегка отличной раскраски для одиночных и двойных кавычек. (Это также помогает с логикой приложения, например, использовать двойные кавычки для текстового вывода и одиночные кавычки только для константоподобных значений.)
Это хороший пример, когда вы не должны выходить из двойных кавычек в первую очередь. Вместо этого просто используйте правильные \"
для атрибутов HTML-атрибутов":
print "<a href=\"{$link}\">click here</a>";
Хотя это также может привести к путанице в синтаксисе, все лучшие IDE/редакторы снова помогают раскрасить экранированные кавычки по-разному.
Эквивалентно забытое открытие "
/'
цитирует рецепт ошибок парсера:
⇓
make_url(login', 'open');
Здесь ', '
станет строковым литералом после голого слова, когда, очевидно, login
должен быть строковым параметром.
Если вы пропустите ,
запятая в блоке создания массива, анализатор будет видеть две последовательные строки:
array( ⇓
"key" => "value"
"next" => "....",
);
Обратите внимание, что в последней строке всегда может содержаться дополнительная запятая, но игнорировать одно между ними непростительно. Это трудно обнаружить без подсветки синтаксиса.
То же самое для вызовов функций:
⇓
myfunc(123, "text", "and" "more")
Общим вариантом являются довольно просто забытые терминаторы строк:
⇓
mysql_evil("SELECT * FROM stuffs);
print "'ok'";
⇑
Здесь PHP жалуется на два строковых литерала, непосредственно следуя друг за другом. Но настоящая причина - незакрытая предыдущая строка, конечно.
Смотрите также
T_STRING
является немного неправильным. Он не относится к цитируемой "string"
. Это означает, что был обнаружен необработанный идентификатор. Это может быть от bare
слов до оставшихся CONSTANT
или имен функций, забытых строк без кавычек или любого простого текста.
Однако эта синтаксическая ошибка является наиболее распространенной для неверных строк. Любая неопределенная и бродячая "
или '
цитата образует недопустимое выражение:
⇓ ⇓
echo "<a href="http://example.com">click here</a>";
Выделение синтаксиса сделает такие ошибки супер очевидными. Важно помнить об использовании обратных косых черт для экранирования \"
двойных кавычек" или \'
одиночных кавычек" - в зависимости от того, что использовалось как оболочка строки.
"
двойных кавычек".echo
/print
вместо вылета и выхода. Еще лучше рассмотрим раздел HEREDOC.См. Также В чем разница между строками с одним кавычком и двойными кавычками в PHP? ,
Если вы пропустите закрытие "
тогда синтаксическая ошибка, как правило, будет реализована позже. Непривязанная строка будет часто потреблять бит кода до следующего предполагаемого значения строки:
⇓
echo "Some text", $a_variable, "and some runaway string ;
success("finished");
⇯
Это не просто буквальный T_STRING
который парсер может протестовать тогда. Еще одним частым изменением является Unexpected '>'
для некотируемого буквального HTML.
Если вы копируете и вставляете код из блога или веб-сайта, иногда вы получаете неверный код. Типографические котировки не соответствуют ожиданиям PHP:
$text = Something something.. + "these ain't quotes";
Типографические/умные кавычки являются символами Юникода. PHP рассматривает их как часть смежного алфавитно-цифрового текста. Например, "these
интерпретируются как константный идентификатор, но любой последующий текстовый литерал затем рассматривается как гонор /T_STRING парсером.
Если у вас есть неисчерпаемое выражение в предыдущих строках, любая следующая инструкция или языковая конструкция рассматривается как необработанный идентификатор:
⇓
func1()
function2();
PHP просто не может знать, хотите ли вы запустить две функции за другой, или если вы хотели бы умножить их результаты, добавить их, сравнить их или запустить только один ||
или другой.
<?xml
в скриптах PHPЭто довольно редко. Но если short_open_tags включены, то вы не можете начинать свои PHP-скрипты с объявления XML:
⇓
<?xml version="1.0"?>
PHP увидит <?
и вернуть его для себя. Он не поймет, для чего предназначен бродячий xml
. Он будет интерпретироваться как постоянный. Но version
будет рассматриваться как еще один литерал/константа. И поскольку анализатор не может понять два последующих литерала/значения без оператора выражения между ними, это будет сбой парсера.
Самой отвратительной причиной для синтаксических ошибок являются символы Юникода, такие как неразрывное пространство. PHP позволяет использовать символы Unicode в качестве имен идентификаторов. Если вы получаете жалобу на парсер T_STRING для совершенно невосприимчивого кода, например:
<?php
print 123;
Вам нужно вырвать другой текстовый редактор. Или даже гекседектор. То, что выглядит как простые пространства и новые строки здесь, может содержать невидимые константы. Java-IDE иногда не обращают внимания на спецификацию UTF-8, искаженные внутри, пространства с нулевой шириной, разделители абзацев и т.д. Попытайтесь переиздать все, удалить пробелы и снова добавить обычные пробелы.
Вы можете сузить его, добавив избыточность ;
разделители операторов при каждом запуске линии:
<?php
;print 123;
Дополнительный ;
точка с запятой преобразует предыдущий невидимый символ в неопределенную константную ссылку (выражение как выражение). Это в свою очередь делает PHP полезным уведомлением.
Переменные в PHP представлены знаком доллара, за которым следует имя переменной.
Знак доллара ($
) - это сигила, которая обозначает идентификатор как имя переменной. Без этого символа идентификатор может быть ключевым словом языка или константой.
Это обычная ошибка, когда код PHP был "переведен" из кода, написанного на другом языке (C, Java, JavaScript и т.д.). В таких случаях декларация типа переменной (когда исходный код был написан на языке, который использует типизированные переменные) также мог прокрасться и произвести эту ошибку.
Если вы используете \
в строке, это имеет особое значение. Это называется " Escape Character " и обычно говорит парсеру буквально воспринимать следующий символ.
Пример: echo 'Jim said \'Hello\'';
будет печатать Jim said 'hello'
Если вы избежите закрывающей цитаты строки, заключительная цитата будет взята буквально и не так, как предполагалось, то есть в качестве печатной цитаты как части строки, а не для закрытия строки. Это будет отображаться как ошибка разбора, обычно после открытия следующей строки или в конце скрипта.
Очень распространенная ошибка при указании путей в Windows: "C:\xampp\htdocs\"
неверна. Вам нужно "C:\\xampp\\htdocs\\"
.
(
Открывающиеся круглые скобки обычно следуют языковым конструкциям, таким как if
/foreach
/for
/array
/list
или запускают арифметическое выражение. Они синтаксически неверны после "strings"
, предыдущего ()
, одиночного $
и в некоторых типичных контекстах объявления.
Редкое появление этой ошибки пытается использовать выражения в качестве параметров функции по умолчанию. Это не поддерживается даже в PHP7:
function header_fallback($value, $expires = time() + 90000) {
Параметры в объявлении функции могут быть только литеральными значениями или постоянными выражениями. В отличие от функций invocations, где вы можете свободно использовать whatever(1+something()*2)
и т.д.
То же самое для деклараций членов класса, где допускаются только значения литерала/константы, а не выражения:
class xyz { ⇓
var $default = get_config("xyz_default");
Поместите такие вещи в конструктор. См. Также Почему атрибуты PHP не позволяют выполнять функции?
Снова отметим, что PHP 7 допускает только var $xy = 1 + 2 +3;
там постоянные выражения.
Использование синтаксиса JavaScript или jQuery не будет работать на PHP по понятным причинам:
<?php ⇓
print $(document).text();
Когда это происходит, оно обычно указывает на неисчерпаемую предыдущую строку; и буквальные <script>
разделы, попадающие в контекст кода PHP.
И isset()
и empty()
являются языковыми встроенными, а не функциями. Им нужно получить доступ к переменной напрямую. Если вы слишком часто добавляете пару круглых скобок, вы должны создать выражение:
⇓
if (isset(($_GET["id"]))) {
То же самое относится к любой языковой конструкции, для которой требуется неявный доступ к имени переменной. Эти встроенные модули являются частью языковой грамматики, поэтому не допускают декоративных дополнительных круглых скобок.
Функции уровня пользователя, требующие ссылки на переменные -but, получают результат выражения passed-, вместо этого приводят к ошибкам во время выполнения.
)
Вы не можете запятнать запятую в вызове функции. PHP ожидает там ценности и, следовательно, жалуется на скорую скобки )
.
⇓
callfunc(1, 2, );
Конечная запятая допускается только в конструкциях array()
или list()
.
Если вы забудете что-то в арифметическом выражении, тогда парсер сдастся. Потому что как это может интерпретировать это:
⇓
$var = 2 * (1 + );
И если вы забыли закрыть )
, тогда вы получите жалобу на неожиданную точку с запятой.
constant
Для забытых переменных $
префиксов в управляющих операциях вы увидите:
↓ ⇓
foreach ($array as wrong) {
PHP здесь иногда говорит вам, что он ожидал a ::
вместо этого. Поскольку переменная class :: $ могла удовлетворять ожидаемому выражению $ variable.
{
Кудрявые фигурные скобки {
и }
заключают блоки кода. И ошибки синтаксиса в отношении них обычно указывают на некорректное вложенность.
if
Чаще всего неуравновешенные (
и )
являются причиной, если парсер жалуется на открытие курчавого {
появляется слишком рано. Простой пример:
⇓
if (($x == $y) && (2 == true) {
Подсчитайте свои parens или используйте IDE, которая помогает с этим. Также не пишите код без пробелов. Показатели удобочитаемости.
Вы не можете использовать фигурные скобки в выражениях. Если вы путаете круглые скобки и кудри, это не будет соответствовать языковому грамматику:
⇓
$var = 5 * {7 + $x};
Для построения идентификатора существует несколько исключений, таких как локальная переменная области ${references}
.
Это довольно редко. Но вы также можете получить {
и }
жалобы парсера на сложные выражения переменных:
⇓
print "Hello {$world[2{]} !";
Хотя есть более высокая вероятность неожиданного }
в таких контекстах.
}
При получении "неожиданную }
" ошибка, вы в основном закрыли блок кода слишком рано.
Это может случиться для любого неисчерпаемого выражения.
И если в последней строке в блоке функции/кода отсутствует трейлинг ;
точка с запятой:
function whatever() {
doStuff()
} ⇧
Здесь синтаксический анализатор не может определить, хотите ли вы еще добавить + 25;
к результату функции или чему-то еще.
{
Иногда вы увидите эту ошибку парсера, когда блок кода был }
закрыт слишком рано или вы забыли открытие {
even:
function doStuff() {
if (true) ⇦
print "yes";
}
} ⇧
В вышеприведенном фрагменте, if
не было открытия {
фигурная скобка. Таким образом, закрытие }
одного ниже стало излишним. И поэтому следующее закрытие }
, которое предназначалось для функции, не было связано с первоначальным открытием {
фигурной скобки.
Такие ошибки еще труднее найти без правильного ввода кода. Используйте сопоставление IDE и скобок.
{
, ожидающий (
Языковые конструкции, для которых требуется заголовок условия/декларации и блок кода, вызовут эту ошибку.
Например, недопустимые функции без списка параметров не разрешены:
⇓
function whatever {
}
И вы также не можете иметь, if
без условия.
⇓
if {
}
Очевидно, это не имеет смысла. То же самое для обычных подозреваемых, for
/foreach
, while
/do
и т.д.
Если у вас есть эта конкретная ошибка, вы определенно должны найти некоторые примеры руководства.
Когда PHP говорит о "неожиданном $end
", это означает, что ваш код закончился преждевременно. (Это сообщение немного вводит в заблуждение, если принять его буквально. Это не о переменной с именем "end end", иногда предполагаемой новичками. Она относится к "концу файла", EOF.)
Причина. Небаланс
{
и}
для кодовых блоков/и объявлений функций или классов.
Это почти всегда о пропавшей }
фигурной скобки, чтобы закрыть предшествующие блоки кода.
Опять же, используйте правильные отступы, чтобы избежать таких проблем.
Используйте IDE с привязкой к скобкам, чтобы узнать, где }
. В большинстве IDE и текстовых редакторах есть сочетания клавиш:
Большинство IDE также выделяют соответствующие фигурные скобки, скобки и круглые скобки. Это позволяет довольно легко проверить их соотношение:
И Unexpected $end
ошибка синтаксиса/парсера Unexpected $end
также может возникать для неиспользуемых выражений или операторов:
$var = func(1,
?>
EOF Итак, сначала посмотрите на конец скриптов. Конечный ;
часто избыточно для последнего оператора в любом скрипте PHP. Но у вас должен быть такой. Именно потому, что он сужает такие проблемы синтаксиса.
Еще одно распространенное явление появляется в строках HEREDOC или NOWDOC. Конечный маркер игнорируется ведущими пробелами, вкладками и т. Д.:
print <<< END
Content...
Content....
END;
# ↑ terminator isn't exactly at the line start
Поэтому анализатор предполагает, что строка HEREDOC продолжается до конца файла (отсюда "Неожиданный конец $"). Практически все IDE и редакторы с подсветкой синтаксиса сделают это очевидным или предупредит об этом.
Если вы используете \
в строке, это имеет особое значение. Это называется " Escape Character " и обычно говорит парсеру буквально воспринимать следующий символ.
Пример: echo 'Jim said \'Hello\'';
будет печатать Jim said 'hello'
Если вы избежите закрывающей цитаты строки, заключительная цитата будет взята буквально и не так, как предполагалось, то есть в качестве печатной цитаты как части строки, а не для закрытия строки. Это будет отображаться как ошибка разбора, обычно после открытия следующей строки или в конце скрипта.
Очень распространенная ошибка при указании путей в Windows: "C:\xampp\htdocs\"
неверна. Вам нужно "C:\\xampp\\htdocs\\"
.
Несколько реже вы можете увидеть эту синтаксическую ошибку при использовании альтернативного синтаксиса для операторов/блоков кода в шаблонах. Использование if:
и else:
и отсутствующий endif;
например.
Условные блоки управления, if
, elseif
и else
следуют простой структуре. Когда вы сталкиваетесь с синтаксической ошибкой, скорее всего, это просто недопустимое вложение блоков → с отсутствующими {
фигурные скобки }
- или слишком много.
{
или }
из-за неправильного отступаНесоответствующие скобки кода являются общими для менее хорошо отформатированного кода, например:
if((!($opt["uniQartz5.8"]!=$this->check58)) or (empty($_POST['poree']))) {if
($true) {echo"halp";} elseif((!$z)or%b){excSmthng(False,5.8)}elseif (False){
Если ваш код выглядит так, начните заново! В противном случае это невозможно для вас или кого-либо еще. Нет смысла демонстрировать это в Интернете, чтобы узнать о помощи.
Вы сможете только исправить это, если вы можете визуально следовать вложенной структуре и соотношению условий if/else и их {
кодовых блоков }
. Используйте свою среду IDE, чтобы узнать, все ли они спарены.
if (true) {
if (false) {
…
}
elseif ($whatever) {
if ($something2) {
…
}
else {
…
}
}
else {
…
}
if (false) { // a second 'if' tree
…
}
else {
…
}
}
elseif (false) {
…
}
Любой double }
}
не просто закрывает ветвь, а предыдущую структуру условий. Поэтому придерживайтесь одного стиля кодирования; не смешивайте и не сопоставляйте вложенные деревья if/else.
Помимо согласованности здесь, оказывается полезным также избегать длительных условий. Используйте временные переменные или функции, чтобы избежать нечитаемых, if
-expressions.
IF
не может использоваться в выражениях Неожиданно частая ошибка новичков пытается использовать оператор if
в выражении, например, выражение печати:
⇓
echo "<a href='" . if ($link == "example.org") { echo …
Конечно, это неверно.
Вы можете использовать тернарный условный, но остерегайтесь уязвимости.
echo "<a href='" . ($link ? "http://yes" : "http://no") . "</a>";
В противном случае сломайте такие выходные конструкции: используйте несколько if
и echo
s.
Еще лучше использовать временные переменные и поместить свои условные обозначения до:
if ($link) { $href = "yes"; } else { $href = "no"; }
echo "<a href='$href'>Link</a>";
Определение функций или методов для таких случаев часто имеет смысл.
Теперь это менее распространено, но несколько кодеров даже пытаются лечить, if
так, как будто это могло вернуть результат:
$var = if ($x == $y) { "true" };
Это структурно идентично использованию, if
внутри конкатенации/выражения строки.
Вам нужно будет использовать назначение в кодовом блоке:
if ($x == $y) { $var = "true"; }
С другой стороны, прибегает к ?:
трехкомпонентному сравнению.
Вы не можете вложить if
внутри условия:
⇓
if ($x == true and (if $y != false)) { ... }
Это явно избыточно, потому что and
(или or
) уже позволяет сравнивать цепочку.
;
точка с запятойЕще раз: каждый блок управления должен быть инструкцией. Если предыдущий фрагмент кода не заканчивается точкой с запятой, то это гарантированная синтаксическая ошибка:
⇓
$var = 1 + 2 + 3
if (true) { … }
Btw, последняя строка в блоке кода {…}
требует точку с запятой.
Теперь, вероятно, неправильно винить определенный стиль кодирования, поскольку эту ловушку слишком легко упускать из виду:
⇓
if ($x == 5);
{
$y = 7;
}
else ←
{
$x = -1;
}
Что происходит чаще, чем вы могли себе представить.
if()
;
он выполнит оператор void. ;
становится пустой {}
!{…}
отделяется от if
и всегда запускается.else
больше не было отношения к открытой конструкции if
, поэтому это привело бы к неожиданной синтаксической ошибке T_ELSE. Это также объясняет также тонкую вариацию этой синтаксической ошибки:
if ($x) { x_is_true(); }; else { something_else(); };
Где ;
после того, как блок кода {…}
завершает целое, if
конструкция, отрезая else
ветвь синтаксически.
Синтаксически это позволяло пропускать фигурные скобки {
... }
для блоков кода в ветвях if
/elseif
/else
. К сожалению, стиль синтаксиса очень распространен для неперевернутых кодировщиков. (По ложному предположению это было бы быстрее ввести или прочитать).
Однако это очень вероятно, чтобы отключить синтаксис. Рано или поздно дополнительные инструкции найдут свой путь в ветвях if/else:
if (true)
$x = 5;
elseif (false)
$x = 6;
$y = 7; ←
else
$z = 0;
Но для фактического использования блоков кода вам нужно написать {
... }
их как таковые!
Даже опытные программисты избегают этого бессловесного синтаксиса или, по крайней мере, понимают его как исключительное исключение из правила.
Одна вещь, чтобы напомнить себе, конечно, условный порядок.
if ($a) { … }
else { … }
elseif ($b) { … }
↑
У вас может быть столько же elseif
сколько вам нужно, но else
нужно пропустить последнее. Вот как это.
Как упоминалось выше, вы не можете иметь контрольные утверждения в объявлении класса:
class xyz {
if (true) {
function ($var) {}
}
Вы либо забыли функцию определения, или закрыты один }
слишком рано в таких случаях.
При смешивании PHP и HTML закрытие }
для if/elseif
должно быть в том же блоке PHP <?php?>
elseif/else
в следующем elseif/else
. Это приведет к ошибке, поскольку закрытие }
для if
должно быть частью elseif
:
<?php if ($x) { ?>
html
<?php } ?>
<?php elseif ($y) { ?>
html
<?php } ?>
Правильная форма <?php } elseif
:
<?php if ($x) { ?>
html
<?php } elseif ($y) { ?>
html
<?php } ?>
Это более или менее вариация неправильного отступа - по-видимому, часто основанная на неправильных намерениях кодирования.
Вы не можете смять другие утверждения между ними, if
и elseif
/else
структурные маркеры:
if (true) {
}
echo "in between"; ←
elseif (false) {
}
?> text <?php ←
else {
}
Либо может произойти только в {…}
блоках кода, а не между маркерами контрольной структуры.
if
и else
.Вы также не можете разделить if/else между различными структурами управления:
foreach ($array as $i) {
if ($i) { … }
}
else { … }
Синтаксической связи между if
и else
. Лексический диапазон foreach
заканчивается на }
, поэтому нет смысла продолжать работу if
.
Если вы испытываете неожиданный T_ENDIF, вы используете альтернативный стиль синтаксиса, if:
⋯ elseif:
⋯ else:
⋯ endif;
, Которые вы должны действительно дважды подумать.
Обычная ловушка сбивает с толку сходство :
двоеточие ;
точка с запятой. (Покрытый в "Точке с запятой слишком рано")
Поскольку отступы сложнее отслеживать в файлах шаблонов, тем больше при использовании альтернативного синтаксиса - это правдоподобно для вашего endif;
не соответствует, if:
Использование } endif;
удваивается, if
-terminator.
В то время как "неожиданный конец $", как правило, цена на забыто закрывающую }
фигурной скобки.
Таким образом, это не синтаксическая ошибка, но стоит упомянуть в этом контексте:
⇓
if ($x = true) { }
else { do_false(); }
Это не сравнение ==
/===
, а назначение =
. Это довольно тонко и легко приведет некоторых пользователей к беспомощному редактированию блоков всего состояния. Следите за непреднамеренными заданиями сначала - когда вы испытываете логическую ошибку /misbeheviour.
Управляющие конструкции, такие как if
, foreach
, for
, while
, list
, global
, return
, do
, print
, echo
могут использоваться только как заявления. Они обычно живут по одной линии.
Довольно универсально, если вы пропустили точку с запятой в предыдущей строке, если парсер жалуется на инструкцию управления:
⇓
$x = myfunc()
if (true) {
Решение: просмотрите предыдущую строку; добавить точку с запятой.
Другое место, где это происходит, в объявлениях классов. В разделе класса вы можете только перечислять инициализации свойств и разделы методов. Никакой код не может находиться там.
class xyz {
if (true) {}
foreach ($var) {}
Такие синтаксические ошибки обычно реализуются для неверно вложенных {
и }
. В частности, когда блоки кода функции закрылись слишком рано.
Большинство языковых конструкций могут использоваться только как утверждения. Они не предназначены для размещения внутри других выражений:
⇓
$var = array(1, 2, foreach($else as $_), 5, 6);
Аналогично, вы не можете использовать if
в строках, математических выражениях или в других местах:
⇓
print "Oh, " . if (true) { "you!" } . " won't work";
// Use a ternary condition here instead, when versed enough.
Для вложения if
-подобных условий в выражении специально вы часто хотите использовать трехмерную оценку ?:
.
То же самое относится к for
, while
, global
, echo
и меньшему расширению list
.
⇓
echo 123, echo 567, "huh?";
В то время как print()
- это встроенный язык, который может использоваться в контексте выражения. (Но редко имеет смысл.)
Вы также не можете использовать do
или if
и другие языковые конструкции для пользовательских функций или имен классов. (Возможно, в PHP7. Но даже тогда было бы нецелесообразно.)
<
>
Операторы сравнения, такие как ==
, >=
, ===
, !=
, <>
, !==
и <=
или <
и >
в основном следует использовать только в выражениях, например, if
выражения. Если синтаксический анализатор жалуется на них, это часто означает неправильный paring или mismatched (
)
parens вокруг них.
В частности, для операторов if
с несколькими сравнениями вы должны позаботиться о правильном подсчете открывающей и закрывающей круглых скобок:
⇓
if (($foo < 7) && $bar) > 5 || $baz < 9) { ... }
↑
Здесь условие if
здесь уже было прервано )
После того, как ваши сравнения становятся достаточно сложными, что часто помогает разбить его на несколько и вложенных друг в друга, if
конструктов скорее.
Обычным новичком является то, что pitfal пытается совместить isset()
или empty()
со сравнением:
⇓
if (empty($_POST["var"] == 1)) {
Или даже:
⇓
if (isset($variable !== "value")) {
Это не имеет смысла для PHP, потому что isset
и empty
- это языковые конструкции, которые принимают только имена переменных. Не имеет смысла сравнивать результат либо потому, что вывод только/уже является логическим.
>=
больше или равно с =>
оператором массиваОба оператора выглядят несколько схожими, поэтому их иногда путают:
⇓
if ($var => 5) { ... }
Вам нужно только помнить, что этот оператор сравнения называется "большим или равным", чтобы понять это правильно.
См. Также: Структура оператора if в PHP
Вы также не можете комбинировать два сравнения, если они относятся к одному и тому же имени переменной:
⇓
if ($xyz > 5 and < 100)
PHP не может вывести, что вы хотели снова сравнить начальную переменную. Выражения, как правило, в паре в соответствии с оператором старшинства, так что к тому времени, когда <
видно, не было бы всего лишь логический результат слева от исходной переменной.
См. Также: неожиданный T_IS_SMALLER_OR_EQUAL
Вы не можете сравнивать с переменной с рядом операторов:
⇓
$reult = (5 < $x < 10);
Это должно быть разбито на два сравнения, каждый против $x
.
На самом деле это больше относится к черным спискам (из-за эквивалентной операторной ассоциативности). Он синтаксически действителен в нескольких языках C-стиля, но PHP не будет интерпретировать его как ожидаемую цепочку сравнения.
>
<
Больше >
меньше или <
операторы не имеют пользовательский T_XXX
Tokenizer имени. И хотя они могут быть неуместными, как и все остальные, вы чаще всего видите, что парсер жалуется на них за неверно настроенные строки и вышитые HTML:
⇓
print "<a href='z">Hello</a>";
↑
Это составляет строка "<a href='z"
>
буквального постоянной Hello
, а затем другой <
сравнения. Или, по крайней мере, как это видит PHP. Фактическая причина и синтаксис ошибка была преждевременно строка "
окончание.
Также невозможно вставить теги запуска PHP:
<?php echo <?php my_func(); ?>
↑
Смотрите также:
Если вы пытаетесь использовать оператор объединения нулей ??
в версии PHP до PHP 7 вы получите эту ошибку.
<?= $a ?? 2; // works in PHP 7+
<?= (!empty($a)) ? $a : 2; // All versions of PHP
Аналогичная ошибка может возникать для типов, допускающих значение NULL, например:
function add(?int $sum): ?int {
Что опять же указывает на использование устаревшей версии PHP (либо CLI-версия php -v
либо веб-сервер ограничен одним phpinfo();
).
T_LNUMBER
относится к "длинному"/номеру.
В PHP и большинстве других языков программирования переменные не могут начинаться с числа. Первым символом должен быть алфавит или символ подчеркивания.
$1 // Bad
$_1 // Good
Довольно часто возникает вопрос о использовании preg_replace
-placeholders "$1"
в контексте PHP:
# ↓ ⇓ ↓
preg_replace("/#(\w+)/e", strtopupper($1) )
Если обратный вызов должен быть указан. (Теперь флаг /e
regex устарел, но иногда он иногда используется неправильно в preg_replace_callback
.)
То же ограничение идентификатора применяется к свойствам объекта, кстати.
↓
$json->0->value
Хотя токенизатор/парсер не разрешает буквенное значение $1
как имя переменной, можно использовать ${1}
или ${"1"}
. Который является синтаксическим обходным решением для нестандартных идентификаторов. (Лучше всего думать об этом как о локальном просмотре области. Но вообще: предпочитайте простые массивы для таких случаев!)
Любопытно, но очень не рекомендуется, парсер PHPs позволяет Unicode-идентификаторы; такой, что $➊
будет действительным. (В отличие от буква 1
).
Неожиданное долго также может возникнуть для объявлений массива - при отсутствии ,
запятые:
# ↓ ↓
$xy = array(1 2 3);
Или же вызовы функций и декларации и другие конструкции:
func(1, 2 3);
function xy($z 2);
for ($i=2 3<$z)
Так обычно бывает один из них ;
или ,
отсутствует для разделения списков или выражений.
И опять же, неверные строки являются частым источником бродячих чисел:
# ↓ ↓
echo "<td colspan="3">something bad</td>";
Такие случаи следует рассматривать более или менее как неожиданные ошибки T_STRING.
Ни функции, ни классы, ни пространства имен не могут быть названы, начиная с номера:
↓
function 123shop() {
Совсем так же, как и для имен переменных.
Это может быть вызвано наличием недопустимых символов в имени переменной. Имена переменных должны соответствовать следующим правилам:
Имена переменных следуют тем же правилам, что и другие метки в PHP. Правильное имя переменной начинается с буквы или подчеркивания, за которой следует любое количество букв, цифр или символов подчеркивания. В качестве регулярного выражения оно выражается следующим образом: "[a-zA-Z_\x7f-\xff] [a-zA-Z0-9 _\x7f-\xff] * '
continue
- это утверждение (например, для или если) и должно выглядеть автономным. Он не может использоваться как часть выражения. Отчасти потому, что continue не возвращает значение, но в выражении каждое подвыражение должно приводить к некоторому значению, поэтому общее выражение приводит к значению. Это разница между выражением и выражением.
Это означает, что continue
не может использоваться в тройном заявлении или в любом заявлении, требующем возвращаемого значения.
То же самое касается break;
конечно. Он также неприменим в контексте выражения, но строгий оператор (на том же уровне, что и foreach
или блок if
).
Теперь это может быть более неожиданным для return
, но это также просто оператор уровня блока. Он возвращает значение (или NULL) для более высокой области/функции, но оно не оценивается как само выражение. → То есть: нет смысла делать return(return(false);;
Синтаксис использует двоеточие - при отсутствии двоеточия произойдет вышеуказанная ошибка
<?php while($query->fetch()): ?>
....
<?php endwhile; ?>
Альтернативой этому синтаксису является использование фигурных скобок
<?php while($query->fetch()) { ?>
....
<?php } ?>