PHP синтаксический анализ / синтаксические ошибки; и как их решить

651

Все сталкиваются с синтаксическими ошибками. Даже опытные программисты делают опечатки. Для новичков это просто часть учебного процесса. Тем не менее, часто легко интерпретировать сообщения об ошибках, такие как:

Ошибка синтаксического анализа PHP: синтаксическая ошибка, неожиданное '{' в index.php в строке 20

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

Всегда смотрите на контекст кода . Синтаксическая ошибка часто скрывается в упомянутых или в предыдущих строках кода . Сравните ваш код с примерами синтаксиса из руководства.

Хотя не каждый случай соответствует другому. Тем не менее, есть некоторые общие шаги для решения синтаксических ошибок . Эти ссылки суммировали общие подводные камни:

Тесно связанные ссылки:

А также:

В то время как Stack Overflow также приветствует новичков, он в основном предназначен для вопросов профессионального программирования.

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

Если твой браузер отображает сообщения об ошибках, такие как «SyntaxError: недопустимый символ», то это на самом деле несвязанные, но - ошибка синтаксиса .


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

марио
источник
1
Для ответа недостаточно данных, но можно написать анализатор с parsekit_compile_string и добавить к нему более дружелюбные ответы. Если интегрировано в вашу IDE, это может быть довольно информативным.
Оуэн Бересфорд
4
Вы вложили внушительный объем работы в это. Уважение к этому. Для учителей, вероятно, очень полезно научиться быстро указывать на ошибки, а также для тех, кто создает IDE или внедряет быстрые исправления. Однако IDE уже выполнит большую часть этой работы за вас, как предлагает @Panique. Кроме того, во многих случаях хороший старт начинается с нуля.
allprog
1
@ Фред-II- Я думаю, что большинство причин похожи на T_IF / T_FOREACH / ...блок. Хоть я и хотел составить более персонализированное резюме для вопросов IF / ELSE / ELSEIF.
Марио
1
@mario Не знаете, как это сформулировать, но может ли этот вопрос быть немного переписан и более структурирован? (временный комментарий)
Rizier123
2
Знаете, мне бы хотелось иметь этот список, когда я изучал PHP много лет назад. Очень полезно, особенно для начинающих.
Чипстер

Ответы:

291

Каковы синтаксические ошибки?

PHP относится к С-стилю и императивным языкам программирования. У него есть жесткие правила грамматики, которые он не может восстановить при обнаружении неуместных символов или идентификаторов. Это не может угадать ваши намерения кодирования.

Синтаксис определения функции абстрактный

Самые важные советы

Есть несколько основных мер предосторожности, которые вы всегда можете предпринять:

  • Используйте правильные отступы кода или используйте любой высокий стиль кодирования. Читаемость предотвращает неровности.

  • Используйте IDE или редактор для PHP с подсветкой синтаксиса . Что также помогает с скобками / балансировкой скобок.

    Ожидается: точка с запятой

  • Прочитайте справочник по языку и примеры в руководстве. Дважды, чтобы стать несколько опытным.

Как интерпретировать ошибки парсера

Типичное сообщение об ошибке синтаксиса гласит:

Ошибка разбора: синтаксическая ошибка, неожиданный T_STRING , ожидание ' ;' в file.php в строке 217

Который перечисляет возможное местоположение синтаксической ошибки. Смотрите упомянутое имя файла и номер строки .

Кличка , такая , как T_STRINGобъясняет , какой символ анализатора / токенизатор не смог обработать окончательно. Однако это не обязательно является причиной синтаксической ошибки.

Важно также рассмотреть предыдущие строки кода . Часто синтаксические ошибки - это просто неудачи, случившиеся ранее. Номер строки ошибки - именно то, где анализатор окончательно отказался от обработки всего этого.

Решение синтаксических ошибок

Есть много подходов, чтобы сузить и исправить синтаксические ошибки.

  • Откройте указанный исходный файл. Посмотрите на упомянутую строку кода .

    • Для убегающих строк и неуместных операторов, это обычно, где вы найдете виновника.

    • Прочитайте строку слева направо и представьте, что делает каждый символ.

  • Более регулярно вы должны смотреть и на предыдущие строки .

    • В частности, пропущенные ;точки с запятой отсутствуют в предыдущем конце строки / оператора. (По крайней мере, со стилистической точки зрения.)

    • Если {блоки кода }неправильно закрыты или вложены, вам, возможно, придется изучить еще больше в исходном коде. Используйте правильный отступ кода, чтобы упростить это.

  • Посмотрите на синтаксис раскраски !

    • Строки, переменные и константы должны иметь разные цвета.

    • Операторы также +-*/.должны быть четко окрашены. Иначе они могут быть в неправильном контексте.

    • Если вы видите, что расцветка строки простирается слишком далеко или слишком коротко, значит, вы нашли неэкранированный или отсутствующий закрывающий "или 'строковый маркер.

    • Наличие двух одинаковых знаков препинания рядом друг с другом также может означать проблемы. Как правило, операторы одиночкой , если это не ++, --или круглые скобки после оператора. Две строки / идентификаторы, непосредственно следующие друг за другом, неверны в большинстве контекстов.

  • Пробел - твой друг . Следуйте любому стилю кодирования.

  • Временно разбить длинные очереди.

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

    • Разделите сложные ifоператоры на отдельные или вложенные ifусловия.

    • Вместо длинных математических формул или логических цепочек используйте временные переменные для упрощения кода. (Более читабельно = меньше ошибок.)

    • Добавьте новые строки между:

      1. Код, который вы можете легко определить как правильный,
      2. Части, в которых вы не уверены,
      3. И строки, на которые парсер жалуется.

      Разделение длинных блоков кода действительно помогает определить источник синтаксических ошибок.

  • Закомментируйте оскорбительный код.

    • Если вы не можете изолировать источник проблемы, начните закомментировать (и, следовательно, временно удалить) блоки кода.

    • Как только вы избавились от ошибки синтаксического анализа, вы нашли источник проблемы. Посмотри внимательнее там.

    • Иногда вы хотите временно удалить завершенные функциональные / методические блоки. (В случае непревзойденных фигурных скобок и неверно с отступом кода.)

    • Если вы не можете решить проблему с синтаксисом, попробуйте переписать закомментированные разделы с нуля .

  • Как новичок, избегайте некоторых запутанных синтаксических конструкций.

    • Тернарный ? :оператор условия может компактировать код и действительно полезен. Но это не помогает удобочитаемости во всех случаях. Предпочитаю простые ifвысказывания, пока не обращен.

    • Альтернативный синтаксис PHP ( if:/ elseif:/ endif;) является общим для шаблонов, но, возможно, менее прост для понимания, чем обычные блоки {кода }.

  • Наиболее распространенные ошибки новичка:

    • Недостающие точки с запятой ;для завершающих операторов / строк.

    • Несоответствующие строковые кавычки для "или 'и неэкранированные кавычки внутри.

    • Забытые операторы, в частности, для .конкатенации строк.

    • Несбалансированные (скобки ). Подсчитайте их в сообщенной строке. Есть ли их равное количество?

  • Не забывайте, что решение одной синтаксической проблемы может раскрыть следующую.

    • Если вы решите одну проблему, но в следующем коде появится другая, вы в основном на правильном пути.

    • Если после редактирования новой синтаксической ошибки появляется в той же строке, то ваша попытка изменения была неудачной. (Не всегда, хотя.)

  • Восстановите резервную копию ранее работающего кода, если вы не можете это исправить.

    • Принять систему управления версиями исходного кода. Вы всегда можете просмотреть 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 общем, или через .htaccessmod_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
Geo
2
Некоторые IDE (например, NetBeans) поддерживают не только подсветку синтаксиса, но и форматирование кода. Если вы привыкли правильно форматировать код и просить IDE переформатировать на всякий случай, время от времени вы можете обнаружить проблемы, такие как непревзойденные скобки.
Хосеп Вальс
115

Я думаю, что эта тема полностью переоценена / слишком сложна. Использование IDE - это ПУТЬ, чтобы полностью избежать любых синтаксических ошибок. Я бы даже сказал, что работать без IDE - это непрофессионально. Почему? Потому что современные IDE проверяют ваш синтаксис после каждого введенного вами символа. Когда вы кодируете, и вся ваша строка становится красной, а большое предупреждающее сообщение показывает точный тип и точное положение синтаксической ошибки, тогда совершенно не нужно искать другое решение.

Использование IDE для проверки синтаксиса означает:

Вы (эффективно) никогда не столкнетесь с синтаксическими ошибками снова, просто потому, что видите их правильно при вводе. Шутки в сторону.

Отличные IDE с проверкой синтаксиса (все они доступны для Linux, Windows и Mac):

  1. NetBeans [бесплатно]
  2. PHPStorm [$ 199 USD]
  3. Затмение с плагином PHP [бесплатно]
  4. Sublime [$ 80 USD] (в основном текстовый редактор, но расширяемый с помощью плагинов, таких как PHP Syntax Parser )
Sliq
источник
2
Это очевидно. Однако, ссылаясь на IDE здесь, не могли бы вы немного рассказать, где они отличаются по синтаксической полезности? Sublime в основном редактор, а не IDE; но потом еще красивее и острее; делает в основном только подсветку синтаксиса, но также подходит для сопоставления скобок. Например, он легко обнаруживает ошибки T_CONSTANT_AND_ENCAPSED мгновенно, в отличие от PHPStorm; который, однако, делает более волнистые линии для встроенных ошибок. Синтаксические подсказки NetBeans раньше были более загадочными, чем даже PHP (скорее, с учетом разрешенных конструкций). Можете ли вы поделиться своим опытом о плюсах / минусах; ваш любимый Eclipse / PDT или ..?
Марио
@mario Я думаю, что вы действительно глубоко разбираетесь в теме, поэтому я действительно не хочу говорить что-то не так здесь, но весь код, который я (и мои товарищи по команде, друзья, которые пишут, фрилансеры) когда-либо писали в IDE, никогда не выполнялся с синтаксической ошибкой. Поэтому я думаю, что, по крайней мере, синтаксическая проверка Netbeans / PHPStorm чрезвычайно мощная. Но, возможно, я неправильно понял ваш вопрос. Дай мне несколько часов ...;)
Sliq
Ваш ответ уже на месте. Подойдет 99% наших вопросов. Однако для контекста здесь я хотел бы найти компромиссное решение, в котором IDE предлагает более удобные для новичков подсказки . Это, вероятно, незначительно для нас, достаточно раскраски и волнистых линий, если вы достаточно разбираетесь. Но я полагаю, что различия могут быть более значительными для начинающих.
Марио
Иногда IDE не является возможным вариантом. Например, быстрое редактирование темы или плагина WordPress. Да, я мог бы скопировать весь код в IDE, но затем мне нужно его открыть, вставить туда все, установить заголовки и все остальное время, потраченное впустую, когда я просто надеюсь на быстрое редактирование. Теперь, если вы разрабатываете новые функции или начинаете с нуля, тогда да, делайте это в IDE. Вы не пожалеете, что потратили немного времени на настройку.
1934286
Я вижу IDE как трейлер, а не просто набор инструментов. Это может быть не FIX, но это может помочь вам найти и предотвратить синтаксические ошибки. Многие ответы здесь говорят о том, что если вы сохраняете свой код чистым, у вас меньше шансов сделать ошибку, и его легче обнаружить. Хорошо с автоматическим отступом, подсказками кода, появлением переменной, автоматически закрывающимися скобками и автоматическим форматированием экономит мне много опечаток в день и является главным преимуществом, почему я использую один. Это не относится ко всему остальному, что выходит за рамки этого вопроса (отладчик, соединитель базы данных, диаграмма uml и т. Д.). IDE сэкономит ваше время и предотвратит не только синтаксические ошибки.
Луи Лоудог Троттье
58

непредвиденный [

В наши дни неожиданная [скобка массива обычно встречается в устаревших версиях PHP. Короткий синтаксис массив доступен , начиная с PHP > = 5.4 . Старые установки только поддерживают array().

$php53 = array(1, 2, 3);
$php54 = [1, 2, 3];
         

Разыменование результата функции массива также недоступно для более старых версий PHP:

$result = get_whatever()["key"];
                      

Справка - Что означает эта ошибка в PHP? - «Синтаксическая ошибка, неожиданная \[» показывает наиболее распространенные и практические обходные пути.

Тем не менее, вам всегда лучше просто обновить установку PHP. Для общих планов веб-хостинга, сначала исследуйте, если, например, 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как постоянное имя.

    Если вы хотели получить доступ к переменной массива (что является типичной причиной здесь), то добавьте $начальный символ - и он станет $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 для сопоставления скобок, чтобы найти преждевременное ]закрытие массива. По крайней мере, используйте больше пробелов и новых строк, чтобы сузить его.

марио
источник
Ссылка 'преобразователи синтаксиса PHP 5.4' github.com/IonutBajescu/short-arrays-to-long-arrays выше не работает.
Данимал Рекс
46

Неожиданный T_VARIABLE

«Неожиданный T_VARIABLE» означает, что есть буквальное $variableимя, которое не вписывается в текущую структуру выражения / оператора.

целенаправленно абстрактный / неточный оператор + $ переменная диаграмма

  1. Отсутствует точка с запятой

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

           
    func1()
    $var = 1 + 2;     # parse error in line +2
  2. Конкатенация строк

    Частая ошибка - это конкатенация строк с забытым .оператором:

                                   
    print "Here comes the value: "  $value;

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

    Строковая интерполяция является основной функцией языка сценариев . Не стыдно его использовать. Не обращайте внимания на любые советы по .микрооптимизации, поскольку конкатенация переменных выполняется быстрее . Это не.

  3. Пропущенные операторы выражений

    Конечно, та же проблема может возникнуть в других выражениях, например, арифметических операциях:

               
    print 4 + 7 $var;

    PHP не может угадать, должна ли переменная быть добавлена, вычтена или сравнена и т. Д.

  4. Списки

    То же самое для списков синтаксиса, как в массивах, где анализатор также указывает ожидаемую запятую, ,например:

                                          
    $var = array("1" => $val, $val2, $val3 $val4);

    Или списки параметров функций:

                                    
    function myfunc($param1, $param2 $param3, $param4)

    Эквивалентно ли вы видите это с помощью listили globalоператоров, или когда отсутствует ;точка с запятой в forцикле.

  5. Объявления класса

    Эта ошибка синтаксического анализатора также возникает в объявлениях классов . Вы можете назначать только статические константы, а не выражения. Таким образом, парсер жалуется на переменные как назначенные данные:

    class xyz {      
        var $value = $_GET["input"];

    Непревзойденные }закрывающие фигурные скобки могут, в частности, привести здесь. Если метод завершается слишком рано (используйте правильный отступ!), То переменная-переменная обычно помещается в тело объявления класса.

  6. Переменные после идентификаторов

    Вы также никогда не сможете, чтобы переменная следовала непосредственно за идентификатором :

                 
    $this->myFunc$VAR();

    Кстати, это распространенный пример, где целью было использование переменных переменных, возможно. В этом случае поиск свойства переменной, $this->{"myFunc$VAR"}();например.

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

  7. Отсутствующие скобки после языковых конструкций

    Поспешная типизация может привести к тому, что забытые открывающие или закрывающие скобки для операторов ifand forи foreach:

           
    foreach $array as $key) {

    Решение: добавить пропущенное отверстие (между оператором и переменной.

                          
    if ($var = pdo_query($sql) {
         $result = 

    Фигурная {скобка не открывает блок кода, не закрывая сначала ifвыражение с )закрывающей скобкой.

  8. Остальное не ожидает условий

         
    else ($var >= 0)

    Решение: Удалить условия elseили использовать elseif.

  9. Нужны скобки для закрытия

         
    function() uses $var {}

    Решение: Добавьте скобки вокруг $var.

  10. Невидимый пробел

    Как упоминалось в справочном ответе «Невидимый блуждающий Unicode» (например, неразрывный пробел ), вы также можете увидеть эту ошибку для ничего не подозревающего кода, например:

    <?php
                              
    $var = new PDO(...);

    Это довольно распространено в начале файлов и для копирования и вставки кода. Проверьте с помощью hexeditor, если ваш код визуально не содержит синтаксических проблем.

Смотрите также

марио
источник
32

Неожиданный T_CONSTANT_ENCAPSED_STRING
Неожиданный T_ENCAPSED_AND_WHITESPACE

Громоздкие имена T_CONSTANT_ENCAPSED_STRINGи T_ENCAPSED_AND_WHITESPACEссылки на цитируемые литералы ."string"

Они используются в разных контекстах, но проблема синтаксиса очень похожа. T_ENCAPSED… предупреждения появляются в строковом контексте в двойных кавычках, в то время как строки T_CONSTANT… часто ошибочны в простых выражениях или операторах PHP.

  1. Неверная интерполяция переменных

    И это чаще всего встречается при неправильной интерполяции переменных PHP:

                                   
    echo "Here comes a $wrong['array'] access";

    Кавычки массивов ключей являются обязательными в контексте PHP. Но в двойных кавычках (или HEREDOCs) это ошибка. Синтаксический анализатор жалуется на заключенные в кавычки 'string', потому что он обычно ожидает буквальный идентификатор / ключ.

    Точнее, для ссылок на массивы допустимо использовать простой синтаксис в стиле PHP2 в двойных кавычках :

    echo "This is only $valid[here] ...";

    Однако для вложенных массивов или более глубоких ссылок на объекты требуется сложный синтаксис фигурных строковых выражений :

    echo "Use {$array['as_usual']} with curly syntax.";

    Если не уверены, это обычно безопаснее использовать. Это часто даже считается более читабельным. И лучшие IDE на самом деле используют для этого разные цвета синтаксиса.

  2. Отсутствует сцепление

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

                           
    print "Hello " . WORLD  " !";

    Хотя это очевидно для вас и меня, PHP просто не может догадаться, что строка должна была быть добавлена ​​туда.

  3. Смешение строк в кавычках

    Та же самая синтаксическая ошибка возникает при смешивании разделителей строк . Строка, начинающаяся с одинарной 'или двойной "кавычки, также заканчивается тем же.

                    
    print "<a href="' . $link . '">click here</a>";
          ⌞⎽⎽⎽⎽⎽⎽⎽⎽⌟⌞⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⌟⌞⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⌟

    Этот пример начался с двойных кавычек. Но двойные кавычки были также предназначены для атрибутов HTML. Однако предполагаемый оператор конкатенации внутри стал интерпретироваться как часть второй строки в одинарных кавычках.

    Совет : Настройте свой редактор / IDE, чтобы использовать слегка отличную раскраску для строк в одинарных и двойных кавычках. (Это также помогает в логике приложения предпочитать, например, строки в двойных кавычках для текстового вывода, а строки в одинарных кавычках только для константных значений.)

    Это хороший пример, где вы не должны в первую очередь вырываться из двойных кавычек. Вместо этого просто используйте правильные \"escape-символы для кавычек атрибутов HTML:

    print "<a href=\"{$link}\">click here</a>";

    Хотя это также может привести к путанице в синтаксисе, все лучшие IDE / редакторы снова помогают, окрашивая экранированные кавычки по-разному.

  4. Отсутствует вводная цитата

    Эквивалентно забываемому открытию "/ 'цитированию рецепт ошибок парсера:

                   
     make_url(login', 'open');

    Здесь ', 'он станет строковым литералом после голого слова, когда, очевидно, loginдолжен был быть строковым параметром.

  5. Списки массивов

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

    array(               
         "key" => "value"
         "next" => "....",
    );

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

  6. Списки параметров функции

    То же самое для вызовов функций :

                             
    myfunc(123, "text", "and"  "more")
  7. Беглые строки

    Распространенным вариантом являются просто забытые терминаторы строк:

                                    
    mysql_evil("SELECT * FROM stuffs);
    print "'ok'";
          ⇑

    Здесь PHP жалуется на два строковых литерала, непосредственно следующих друг за другом. Но настоящая причина, конечно, в незакрытой предыдущей строке.

Смотрите также

марио
источник
27

Неожиданный T_STRING

T_STRINGэто немного неправильно. Это не относится к цитируемому "string". Это означает, что был обнаружен необработанный идентификатор. Это может варьироваться от bareслов до оставшихся CONSTANTили имен функций, забытых строк без кавычек или любого простого текста.

  1. Ошибочные строки

    Однако эта синтаксическая ошибка наиболее распространена для неверно цитируемых строковых значений. Любые unescaped и беспризорные "или 'цитаты сформируют недопустимое выражение

                                     
     echo "<a href="http://example.com">click here</a>";

    Подсветка синтаксиса сделает такие ошибки супер очевидными. Важно не забывать использовать обратную косую черту для экранирования \"двойных кавычек или \'одинарных кавычек - в зависимости от того, какая строка использовалась в качестве вложенной строки .

    • Для удобства вы должны предпочесть внешние одинарные кавычки при выводе простого HTML с двойными кавычками внутри.
    • Используйте строки в двойных кавычках, если вы хотите интерполировать переменные, но затем следите за экранированием "двойных кавычек.
    • Для более длительного выхода, предпочитают несколько echo/ printлинии вместо побега в и. Еще лучше рассмотреть раздел HEREDOC .

    Другой пример - использование записи PHP внутри HTML-кода, созданного с помощью PHP:

    $text = '<div>some text with <?php echo 'some php entry' ?></div>'

    Это происходит, если $textон большой и содержит много строк, и разработчик не видит всего значения переменной PHP и сосредотачивается на части кода, забывая об ее источнике. Пример здесь

    Смотрите также В чем разница между одинарными и двойными кавычками в PHP? ,

  2. Незакрытые строки

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

                                                           
    echo "Some text", $a_variable, "and some runaway string ;
    success("finished");
             ⇯

    Тогда T_STRINGпарсер может протестовать не только буквально . Еще один частый вариант - это Unexpected '>'буквальный HTML без кавычек.

  3. Непрограммирующие строковые кавычки

    Если вы копируете и вставляете код из блога или веб-сайта, у вас иногда получается неверный код. Типографские кавычки - это не то, что ожидает PHP:

    $text = Something something..’ + these ain't quotes”;

    Типографские / умные кавычки являются символами Юникода. PHP рассматривает их как часть буквенно-цифрового текста. Например ”these, интерпретируется как постоянный идентификатор. Но любой последующий текстовый литерал затем рассматривается синтаксическим анализатором как голое слово / T_STRING.

  4. Пропущенная точка с запятой; снова

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

           
    func1()
    function2();

    PHP просто не может знать, хотели ли вы запускать две функции за другой, или вы хотели умножить их результаты, добавить их, сравнить их или запустить только одну ||или другую.

  5. Короткие открытые теги и <?xmlзаголовки в скриптах PHP

    Это довольно необычно. Но если включены short_open_tags, вы не можете начать свои PHP-скрипты с объявления XML :

          
    <?xml version="1.0"?>

    PHP увидит <?и исправит это для себя. Он не поймет, для чего предназначался шальной xml. Это будет интерпретировано как константа. Но versionбудет рассматриваться как еще один буквальный / постоянный. А поскольку синтаксический анализатор не может иметь смысла двух последующих литералов / значений без оператора выражения между ними, это будет ошибкой синтаксического анализатора.

  6. Невидимые символы Юникода

    Наиболее отвратительной причиной синтаксических ошибок являются символы Юникода, такие как неразрывный пробел . PHP допускает использование символов Юникода в качестве имен идентификаторов. Если вы получили жалобу парсера T_STRING на совершенно неожиданный код, такой как:

    <?php
        print 123;

    Вам нужно вырвать другой текстовый редактор. Или даже гекседитор. То, что здесь выглядит как простые пробелы и символы новой строки, может содержать невидимые константы. Основанные на Java IDE иногда забывают о спецификации UTF-8, искривленной внутри, пробелах нулевой ширины, разделителях абзацев и т. Д. Попробуйте переопределить все, удалить пробелы и добавить в них нормальные пробелы.

    Вы можете сузить это с добавлением избыточных ;разделителей операторов в начале каждой строки:

    <?php
        ;print 123;

    Дополнительная ;точка с запятой здесь преобразует предыдущий невидимый символ в неопределенную константную ссылку (выражение как выражение). Что, в свою очередь, заставляет PHP создавать полезное уведомление.

  7. Знак `$` отсутствует перед именами переменных

    Переменные в PHP представлены знаком доллара, за которым следует имя переменной.

    Знак доллара ( $) - это символ, который отмечает идентификатор как имя переменной. Без этого символа идентификатор может быть ключевым словом языка или константой .

    Это распространенная ошибка, когда код PHP был «переведен» из кода, написанного на другом языке (C, Java, JavaScript и т. Д.). В таких случаях объявление типа переменной (когда исходный код был написан на языке, использующем типизированные переменные) также может ускользнуть и вызвать эту ошибку.

  8. Избежавшие кавычки

    Если вы используете \в строке, это имеет особое значение. Это называется « Escape Character » и обычно говорит парсеру буквально брать следующий символ.

    Пример: echo 'Jim said \'Hello\'';напечатаетJim said 'hello'

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

    Очень распространенная ошибка при указании путей в Windows: "C:\xampp\htdocs\"неверно. Вам нужно "C:\\xampp\\htdocs\\".

марио
источник
18

непредвиденный (

Открывающие скобки обычно следуют за языковыми конструкциями, такими как if/ foreach/ for/ array/ listили начинают арифметическое выражение. Они синтаксически некорректны после "strings", предыдущего (), одинокого $и в некоторых типичных контекстах объявления.

  1. Параметры объявления функции

    Более редкое вхождение для этой ошибки пытается использовать выражения в качестве параметров функции по умолчанию . Это не поддерживается даже в PHP7:

    function header_fallback($value, $expires = time() + 90000) {

    Параметры в объявлении функции могут быть только литеральными значениями или константными выражениями. В отличие от вызовов функций, где вы можете свободно использовать whatever(1+something()*2)и т. Д.

  2. Свойства класса по умолчанию

    То же самое для объявлений членов класса , где допускаются только литеральные / константные значения, а не выражения:

    class xyz {                   
        var $default = get_config("xyz_default");

    Поместите такие вещи в конструктор. См. Также Почему атрибуты PHP не разрешают функции?

    Еще раз обратите внимание, что PHP 7 допускает только var $xy = 1 + 2 +3;постоянные выражения там.

  3. Синтаксис JavaScript в PHP

    Использование синтаксиса JavaScript или jQuery не будет работать в PHP по понятным причинам:

    <?php      
        print $(document).text();

    Когда это происходит, это обычно указывает на неопределенную предшествующую строку; и буквальные <script>разделы просачиваются в контекст кода PHP.

  4. isset (()), пустой, ключ, следующий, текущий

    Оба isset()и empty()являются встроенными языками, а не функциями. Им нужно получить доступ к переменной напрямую . Если вы ненароком добавите пару скобок слишком много, то вы создадите выражение:

              
    if (isset(($_GET["id"]))) {

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

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


непредвиденный )

  1. Отсутствующий параметр функции

    Вы не можете иметь запятые в конце вызова функции . PHP ожидает значения и поэтому жалуется на закрывающую )скобку.

                  
    callfunc(1, 2, );

    Завершающая запятая допускается только в конструкции array()или list().

  2. Незаконченные выражения

    Если вы что-то забудете в арифметическом выражении, то парсер сдастся. Потому что как это должно интерпретировать это:

                   
    $var = 2 * (1 + );

    И если вы забудете )даже закрытие , вы получите жалобу на неожиданную точку с запятой.

  3. Foreach как constant

    Для забытых $префиксов переменных в управляющих операторах вы увидите:

                           
    foreach ($array as wrong) {

    PHP здесь иногда говорит вам, что он ожидал ::. Потому что переменная class :: $ могла бы удовлетворить ожидаемое выражение переменной $.


непредвиденный {

Фигурные скобки {и }кодовые блоки. А синтаксические ошибки о них обычно указывают на неправильное вложение.

  1. Непревзойденные подвыражения в if

    Чаще всего несбалансированно (и) является причиной, если парсер жалуется на то, что открывающееся фигурное выражение {появляется слишком рано. Простой пример:

                                  
    if (($x == $y) && (2 == true) {

    Подсчитайте свои скобки или используйте IDE, которая поможет с этим. Также не пишите код без пробелов. Читаемость имеет значение.

  2. {и} в контексте выражения

    Вы не можете использовать фигурные скобки в выражениях. Если вы перепутаете скобки и фигурные скобки, это не будет соответствовать грамматике языка:

               
    $var = 5 * {7 + $x};

    Есть несколько исключений для построения идентификатора, таких как локальная переменная области видимости ${references}.

  3. Переменные переменные или выражения curly var

    Это довольно редко. Но вы также можете получать {и }анализировать жалобы для сложных выражений переменных:

                          
    print "Hello {$world[2{]} !";

    Хотя }в таких ситуациях вероятность неожиданности выше .


непредвиденный }

Получая «неожиданную }» ошибку, вы в основном закрывали блок кода слишком рано.

  1. Последнее утверждение в блоке кода

    Это может произойти для любого неопределенного выражения.

    И если в последней строке в блоке функции / кода отсутствует конечная ;точка с запятой:

    function whatever() {
        doStuff()
    }            

    Здесь синтаксический анализатор не может сказать, если вы, возможно, все еще хотите добавить + 25;к результату функции или что-то еще.

  2. Неправильное вложение блоков / Забыли {

    Иногда вы будете видеть эту ошибку синтаксического анализатора, когда блок кода был }закрыт слишком рано, или вы забыли {даже открытие :

    function doStuff() {
        if (true)    
            print "yes";
        }
    }   

    В приведенном фрагменте ifне было открывающейся {фигурной скобки. Таким образом, закрытие }ниже стало излишним. И поэтому следующее закрытие }, которое предназначалось для функции, не было связано с исходной {фигурной скобкой открытия .

    Такие ошибки еще сложнее найти без правильного отступа кода. Используйте IDE и сопоставление скобок.


непредвиденный { , ожидая(

Языковые конструкции, которые требуют заголовка условия / объявления и блока кода, вызовут эту ошибку.

  1. Списки параметров

    Например, неправильно объявленные функции без списка параметров не допускаются:

                     
    function whatever {
    }
  2. Условия контрольной выписки

    И вы также не можете иметь ifбез условия .

      
    if {
    }

    Что не имеет смысла, очевидно. То же самое для обычных подозреваемых, for/ foreach, while/ doи т. Д.

    Если у вас есть эта конкретная ошибка, вам определенно следует поискать несколько ручных примеров.

марио
источник
1
Я искал ответ на мой вопрос в этом посте, но сам нашел ответ на проблему - «Неожиданный {», поэтому я хотел поделиться с моим ответом - для меня проблема заключалась в кодировании разрыва строки - каким-то образом некоторые из моих файлы использовали разрывы строк в macintosh, но когда я изменил их на разрывы строк в Windows - моя проблема (на локальном хосте (WAMP) все работает, но на веб-сервере linux нет) была решена.
Эдгар Айварс
@EdgarsAivars Спасибо за ваш комментарий! Разрывы строк для конкретных платформ - действительно редкая и сложная проблема. Я, наверное, упомяну это и здесь. (Это было только что упомянуто в стороне в другом справочном ответе .)
Марио
Я обнаружил, что получение неожиданного} связано с тем, что часть моего кода использует короткий тег php <? вместо <? php - мне потребовалось некоторое время, чтобы найти этот, который работал на других серверах.
c7borg
14

Неожиданный конец $

Когда PHP говорит о «неожиданном $end», это означает, что ваш код закончился преждевременно. (Это сообщение немного вводит в заблуждение, если воспринимать его буквально. Оно не относится к переменной с именем $ end, как иногда предполагают новички. Оно относится к «концу файла» EOF,.)

Причина: Несбалансированность {и }для блоков кода / и объявлений функций или классов.

В большинстве случаев речь идет об отсутствующей }фигурной скобке для закрытия предыдущих блоков кода.

  • Опять же, используйте правильные отступы, чтобы избежать таких проблем.

  • Используйте IDE с сопоставлением скобок, чтобы узнать, где это }не так. В большинстве IDE и текстовых редакторах есть сочетания клавиш:

    • NetBeans, PhpStorm, Komodo: Ctrl[иCtrl]
    • Затмение, Аптана: CtrlShiftP
    • Атом, возвышенное: Ctrlm- Zend StudioCtrlM
    • Джани, Блокнот ++: CtrlB- Джо: CtrlG- Emacs: C-M-n- Vim:%

Большинство IDE также выделяют соответствующие скобки, скобки и скобки. Что позволяет довольно легко проверить их соотношение:

Соответствие скобок в IDE

Неопределенные выражения

И Unexpected $endошибка синтаксиса / синтаксического анализатора также может произойти для неопределенных выражений или операторов:

  • $var = func(1, ?>EOF

Итак, сначала посмотрите на конец сценария. Трейлинг ;часто избыточен для последнего оператора в любом скрипте PHP. Но ты должен быть один. Именно потому, что он сужает такие проблемы синтаксиса.

Отступы маркеры HEREDOC

Другое распространенное вхождение встречается со строками HEREDOC или NOWDOC . Завершающий маркер игнорируется начальными пробелами, символами табуляции и т. Д .:

print <<< END
    Content...
    Content....
  END;
# ↑ terminator isn't exactly at the line start

Поэтому синтаксический анализатор предполагает, что строка HEREDOC будет продолжаться до конца файла (следовательно, «Неожиданный $ end»). Практически все IDE и редакторы с подсветкой синтаксиса сделают это очевидным или предупредят об этом.

Избежавшие кавычки

Если вы используете \в строке, это имеет особое значение. Это называется « Escape Character » и обычно говорит парсеру буквально брать следующий символ.

Пример: echo 'Jim said \'Hello\'';напечатаетJim said 'hello'

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

Очень распространенная ошибка при указании путей в Windows: "C:\xampp\htdocs\"неверно. Вам нужно "C:\\xampp\\htdocs\\".

Альтернативный синтаксис

Несколько реже можно увидеть эту синтаксическую ошибку при использовании альтернативного синтаксиса для блоков операторов / кода в шаблонах. Использование if:и else:и отсутствует, endif;например.

Смотрите также:

марио
источник
14

Неожиданный T_IF
Неожиданный T_ELSEIF
Неожиданный T_ELSE
Неожиданный T_ENDIF

Условные блоки управления if, elseifи elseследовать за простую структуру. Когда вы сталкиваетесь с синтаксической ошибкой, это, скорее всего, просто недопустимое вложение блоков → с отсутствующими {фигурными скобками }- или слишком много.

введите описание изображения здесь

  1. Отсутствует {или }из-за неправильного отступа

    Несоответствующие скобки кода являются общими для менее хорошо отформатированного кода, такого как:

    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) {
        
    }

    Любой двойник } }не просто закроет ветку, но и структуру предыдущего условия. Поэтому придерживайтесь одного стиля кодирования; не смешивать и сочетать во вложенных деревьях if / else.

    Помимо последовательности здесь оказывается полезным избегать и длительных условий. Используйте временные переменные или функции, чтобы избежать нечитаемых ifвыражений.

  2. IF нельзя использовать в выражениях

    Удивительно частая ошибка новичка - попытка использовать ifоператор в выражении, например оператор print:

                       
    echo "<a href='" . if ($link == "example.org") { echo 

    Что, конечно, неверно.

    Вы можете использовать троичный условный код , но остерегайтесь влияния читабельности.

    echo "<a href='" . ($link ? "http://yes" : "http://no") . "</a>";

    В противном случае разбейте такие выходные структуры: используйте несколько ifs и echos .
    А еще лучше, используйте временные переменные и поместите ваши условия перед:

    if ($link) { $href = "yes"; } else { $href = "no"; }
    echo "<a href='$href'>Link</a>";

    Определение функций или методов для таких случаев также часто имеет смысл.

    Блоки управления не возвращают «результаты»

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

    $var = if ($x == $y) { "true" };

    Что структурно идентично использованию ifвнутри конкатенации / выражения строки.

    • Но управляющие структуры (если / foreach / while) не имеют «результата» .
    • Литеральная строка «true» также будет просто пустым утверждением.

    Вам придется использовать назначение в блоке кода :

    if ($x == $y) { $var = "true"; }

    В качестве альтернативы прибегают к ?:троичному сравнению.

    Если в Если

    Вы не можете вкладыватьif в условия либо:

                        
    if ($x == true and (if $y != false)) { ... }

    Что явно избыточно, потому что and(или or) уже позволяет сравнивать цепочки.

  3. Забытые ;точки с запятой

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

                    
    $var = 1 + 2 + 3
    if (true) {  }

    Кстати, последняя строка в {…}блоке кода тоже нуждается в точке с запятой.

  4. Точка с запятой слишком рано

    Теперь, вероятно, неправильно обвинять конкретный стиль кодирования, поскольку эту ловушку слишком легко упустить из виду:

                
    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синтаксически разрывая ветвь.

  5. Не используя блоки кода

    Синтаксически разрешено пропускать фигурные скобки {... }для блоков кода в if/ elseif/ elseветках. К сожалению, это синтаксический стиль, очень распространенный для неверсированных кодеров. (Под ложным предположением это было быстрее напечатать или прочитать).

    Однако это, скорее всего, нарушит синтаксис. Рано или поздно дополнительные операторы попадут в ветки if / else:

    if (true)
        $x = 5;
    elseif (false)
        $x = 6;
        $y = 7;     
    else
        $z = 0;

    Но чтобы фактически использовать блоки кода, вы должны написать {... }их как таковые!

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

  6. Остальное / Elseif в неправильном порядке

    Конечно , нужно напомнить себе об условном заказе .

    if ($a) {  }
    else {  }
    elseif ($b) {  }
    

    Вы можете иметь столько elseifs, сколько хотите, но elseдолжны идти последними . Вот только как это.

  7. Объявления класса

    Как упоминалось выше , вы не можете иметь управляющие операторы в объявлении класса:

    class xyz {
        if (true) {
            function ($var) {}
        }

    В таких случаях вы либо забыли определение функции , либо закрыли ее }слишком рано.

  8. Неожиданный T_ELSEIF / T_ELSE

    При смешивании PHP и HTML закрытие }для if/elseifдолжно быть в том же блоке PHP, <?php ?>что и следующий 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 } ?>

    Это более или менее вариант неправильного отступа - предположительно часто основанный на неправильных намерениях кодирования.
    Вы не можете помять другие операторы Inbetween if и elseif/ elseструктурных лексем:

    if (true) {
    }
    echo "in between";    
    elseif (false) {
    }
    ?> text <?php      
    else {
    }

    Либо может происходить только в {…}кодовых блоках, но не между токенами структуры управления.

    • В любом случае это не имеет смысла. Это не так , что есть некоторое «неопределенное» состояние , когда PHP прыгает между ifи elseветвями.
    • Вы должны будете решить, где операторы печати принадлежат / или если они должны повторяться в обеих ветвях.

    Вы также не можете разделить if / else между различными структурами управления:

    foreach ($array as $i) {
        if ($i) {  }
    }
    else {  }

    Там нет синтаксической связи между ifи else. На этом foreachлексическая область видимости заканчивается }, поэтому нет смысла продолжать ifструктуру.

  9. T_ENDIF

    Если к неожиданному T_ENDIF предъявляются претензии, вы используете альтернативный стиль синтаксиса if:elseif:else:endif;. О чем стоит подумать дважды.

    • Типичная ошибка путает устрашающе подобное :двоеточие для ;точкой с запятой . (В «Точка с запятой слишком рано»)

    • Поскольку отступы в файлах шаблонов отслеживать сложнее, тем более при использовании альтернативного синтаксиса - вероятно, ваш endif;не соответствует ни одному if:.

    • Используя } endif; это в два раза if -terminator.

    В то время как «неожиданный конец $» - это обычно цена за забытую }фигурную скобку.

  10. Назначение против сравнения

    Итак, это не синтаксическая ошибка, но стоит упомянуть в этом контексте:

           
    if ($x = true) { }
    else { do_false(); }

    Это не ==/ ===сравнение, но =назначение . Это довольно тонко, и некоторые пользователи легко могут бесполезно редактировать целые блоки условий. Сначала следите за непреднамеренными заданиями - всякий раз, когда вы испытываете логическую ошибку / неправильное поведение.

марио
источник
11

Неожиданный T_IS_EQUAL
Неожиданный T_IS_GREATER_OR_EQUAL
Неожиданный T_IS_IDENTICAL
Неожиданный T_IS_NOT_EQUAL
Неожиданный T_IS_NOT_IDENTICAL
Неожиданный T_IS_SMALLER_OR_EQUAL
Неожиданный <
Неожиданный>

Операторы сравнения , такие как ==, >=, ===, !=,<> , !==и , <=или <и в >основном следует использовать только в выражениях, например, ifвыражения. Если синтаксический анализатор жалуется на них, то это часто означает неправильный анализ или несовпадающие ( )скобки вокруг них.

  1. Паренс группировка

    В частности, для ifоператоров с множественными сравнениями вы должны позаботиться о правильном подсчете открывающей и закрывающей скобок :

                            
    if (($foo < 7) && $bar) > 5 || $baz < 9) { ... }
                          

    Здесь if условие здесь уже было прекращено)

    Как только ваши сравнения становятся достаточно сложными, это часто помогает разделить их на несколько вложенных ifконструкций.

  2. isset () пюре со сравнением

    Обычным новичком является то, что Питфал пытается объединить isset()илиempty() сравнить:

                            
    if (empty($_POST["var"] == 1)) {

    Или даже:

                        
    if (isset($variable !== "value")) {

    Это не имеет смысла для PHP, потому что isset и emptyявляются языковыми конструкциями, которые принимают только имена переменных. Сравнивать результат тоже не имеет смысла, потому что вывод только / уже логический.

  3. Смешение >= больше или равно=> оператором массива

    Оба оператора выглядят несколько похожими, поэтому они иногда путаются:

             
    if ($var => 5) { ... }

    Вам нужно только помнить, что этот оператор сравнения называется « больше, чем или равно », чтобы понять его правильно.

    Смотрите также: Если структура оператора в PHP

  4. Нечего сравнивать

    Вы также не можете объединить два сравнения, если они имеют одно и то же имя переменной:

                     
    if ($xyz > 5 and < 100)

    PHP не может сделать вывод, что вы хотели снова сравнить исходную переменную. Выражения обычно объединяются в соответствии с приоритетом оператора , поэтому к тому времени< видны, от исходной переменной останется только логический результат.

    Смотрите также: неожиданно T_IS_SMALLER_OR_EQUAL

  5. Цепочки сравнения

    Вы не можете сравнивать переменную с рядом операторов:

                      
     $reult = (5 < $x < 10);

    Это должно быть разбито на два сравнения, каждое против $x.

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

  6. Неожиданный >
    неожиданный<

    Операторы больше >или меньше <не имеют собственного T_XXXимени токенизатора. И хотя они могут быть неуместны, как и все остальные, вы все чаще видите, как парсер жалуется на них из-за неверно цитируемых строк и затертого HTML:

                            
    print "<a href='z">Hello</a>";
                     ↑

    Это означает, что строка "<a href='z"сравнивается >с литеральной константой, Helloа затем выполняется другое <сравнение. Или, по крайней мере, так видит PHP. Фактическая причина и синтаксическая ошибка была преждевременной строкой" завершение .

    Также невозможно вложить стартовые теги PHP:

    <?php echo <?php my_func(); ?>

Смотрите также:

марио
источник
11

Неожиданный T_IF
Неожиданный T_FOREACH
Неожиданный T_FOR
Неожиданный T_WHILE
Неожиданный T_DO
Неожиданный T_ECHO

Контроль конструкции , такие , как if, foreach, for, while, list, global, return, do, print, echoможет быть использован только в качестве заявлений. Они обычно проживают на линии самостоятельно.

  1. Точка с запятой; где ты?

    В большинстве случаев вы пропустили точку с запятой в предыдущей строке, если анализатор жалуется на оператор управления:

                 
    $x = myfunc()
    if (true) {

    Решение: посмотрите на предыдущую строку; добавить точку с запятой.

  2. Объявления класса

    Другое место, где это происходит, в объявлениях классов . В разделе класса вы можете перечислить только инициализации свойств и разделы методов. Никакой код не может находиться там.

    class xyz {
        if (true) {}
        foreach ($var) {}

    Такие синтаксические ошибки обычно материализуются для неправильно вложенных {и }. В частности, когда блоки кода функции закрываются слишком рано.

  3. Заявления в контексте выражения

    Большинство языковых конструкций можно использовать только как операторы . Они не предназначены для размещения внутри других выражений:

                       
    $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()что это встроенный язык, который может использоваться в контексте выражения. (Но редко имеет смысл.)

  4. Зарезервированные ключевые слова в качестве идентификаторов

    Вы также не можете использовать doили ifи другие языковые конструкции для пользовательских функций или имен классов. (Возможно, в PHP 7. Но даже тогда это было бы нецелесообразно.)

марио
источник
7

Неожиданный '?'

Если вы пытаетесь использовать оператор объединения нулей ??в версии 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();).

Джон Конде
источник
5

Неожиданный T_LNUMBER

Маркер T_LNUMBERотносится к «длинному» / номеру.

  1. Неверные имена переменных

    В PHP и большинстве других языков программирования переменные не могут начинаться с цифры. Первый символ должен быть буквенным или подчеркиванием.

    $1   // Bad
    $_1  // Good

    *

    • Довольно часто возникает необходимость использования preg_replace-placeholder "$1"в контексте PHP:

      #                         ↓            ⇓  ↓
      preg_replace("/#(\w+)/e",  strtopupper($1) )

      Где обратный вызов должен был быть процитирован. (Теперь /eфлаг регулярного выражения устарел. Но иногда он по-прежнему неправильно используется в preg_replace_callbackфункциях.)

    • То же ограничение идентификатора применяется к свойствам объекта , кстати.

             
      $json->0->value
    • Хотя токенизатор / парсер не допускает литерал в $1качестве имени переменной, можно использовать ${1}или ${"1"}. Это синтаксический обход нестандартных идентификаторов. (Лучше всего думать об этом как о поиске в локальной области видимости. Но в целом: для таких случаев предпочитайте простые массивы!)

    • Забавно, но очень не рекомендуется, парсер PHP позволяет использовать Unicode-идентификаторы; такой, что $➊будет в силе. (В отличие от буквального 1).

  2. Блуждающая запись массива

    Неожиданное длинное также может произойти для объявлений массива - при отсутствии ,запятых:

    #            ↓ ↓
    $xy = array(1 2 3);

    Или аналогично вызовам и объявлениям функций и другим конструкциям:

    • func(1, 2 3);
    • function xy($z 2);
    • for ($i=2 3<$z)

    Так что обычно есть один из ;или ,отсутствует для разделения списков или выражений.

  3. Неверно цитируемый HTML

    И опять же, неверно цитируемые строки являются частым источником случайных чисел:

    #                 ↓ ↓          
    echo "<td colspan="3">something bad</td>";

    Такие случаи должны рассматриваться более или менее как непредвиденные ошибки T_STRING .

  4. Другие идентификаторы

    Ни функции, ни классы, ни пространства имен не могут быть названы, начиная с номера:

             
    function 123shop() {

    Почти так же, как и для имен переменных.

марио
источник
2

Неожиданный '='

Это может быть вызвано наличием недопустимых символов в имени переменной. Имена переменных должны соответствовать следующим правилам:

Имена переменных следуют тем же правилам, что и другие метки в PHP. Допустимое имя переменной начинается с буквы или подчеркивания, за которым следует любое количество букв, цифр или подчеркивания. Как регулярное выражение, оно будет выражаться так: '[a-zA-Z_ \ x7f- \ xff] [a-zA-Z0-9_ \ x7f- \ xff] *'

Джон Конде
источник
Хорошее дополнение Джон.
Funk Forty Niner
1

Неожиданное продолжение (T_CONTINUE)

continueявляется утверждением (например, for или if) и должно отображаться отдельно. Его нельзя использовать как часть выражения. Отчасти потому, что continue не возвращает значение, но в выражении каждое подвыражение должно приводить к некоторому значению, поэтому общее выражение приводит к значению. В этом разница между утверждением и выражением.

Это означает, что continueнельзя использовать в троичной инструкции или в любой инструкции, которая требует возвращаемого значения.

Неожиданный перерыв (T_BREAK)

То же самое касается break;конечно. Это также не применимо в контексте выражения, но строгое утверждение (на том же уровне, что foreachи ifблок).

Неожиданный возврат (T_RETURN)

Теперь это может быть более удивительным return, но это также просто утверждение уровня блока . Он возвращает значение (или NULL) в более высокую область видимости / функцию, но не оценивает само выражение. → То есть: нет смысла делатьreturn(return(false);;

марио
источник
1

Неожиданный "."

Это может произойти, если вы пытаетесь использовать оператор splat ( ...) в неподдерживаемой версии PHP.

... впервые стала доступна в PHP 5.6 для захвата переменного количества аргументов функции:

function concatenate($transform, ...$strings) {
    $string = '';
    foreach($strings as $piece) {
        $string .= $piece;
    }
    return($transform($string));
}

echo concatenate("strtoupper", "I'd ", "like ", 4 + 2, " apples");
// This would print:
// I'D LIKE 6 APPLES

В PHP 7.4 вы можете использовать его для выражений Array .

$parts = ['apple', 'pear'];
$fruits = ['banana', 'orange', ...$parts, 'watermelon'];
// ['banana', 'orange', 'apple', 'pear', 'watermelon'];
Джон Конде
источник
0

Неожиданный «конец» (T_ENDWHILE)

Синтаксис использует двоеточие - если двоеточие отсутствует, возникнет указанная выше ошибка.

<?php while($query->fetch()): ?>
 ....
<?php endwhile; ?>

Альтернативой этому синтаксису являются фигурные скобки:

<?php while($query->fetch()) { ?>
  ....
<?php } ?>

http://php.net/manual/en/control-structures.while.php

mplungjan
источник
0

Сообщение об ошибке, которое начинается, Parse error: syntax error, unexpected ':'может быть вызвано ошибочной записью статической ссылки на класс Class::$Variableкак Class:$Variable.

Дэвид Спектор
источник