Помилки розбору / синтаксису PHP; і як їх вирішити


652

Усі стикаються з синтаксичними помилками. Навіть досвідчені програмісти роблять помилки. Для новачків це лише частина навчального процесу. Однак інтерпретувати повідомлення про помилки часто легко:

Помилка розбору PHP: помилка синтаксису, несподівана '{' в index.php у рядку 20

Несподіваний символ не завжди є справжнім винуватцем. Але номер рядка дає приблизне уявлення про те, з чого почати шукати.

Завжди дивіться на контекст коду . Синтаксис помилка часто приховує в згаданих або в попередніх рядках коду . Порівняйте свій код із прикладами синтаксису з посібника.

Хоча не кожен випадок відповідає іншому. Але є кілька загальних кроків для вирішення синтаксичних помилок . Ці посилання підсумовували загальні підводні камені:

Тісно пов’язані посилання:

І:

Хоча Stack Overflow також вітає новинки кодерів, він в основному орієнтований на питання професійного програмування.

  • Відповідь на помилки кодування кожного та вузькі помилки друку вважається здебільшого поза темою.
  • Тому, будь ласка, знайдіть час, щоб виконати основні дії , перш ніж публікувати запити на виправлення синтаксису.
  • Якщо вам все-таки доведеться, будь-ласка, покажіть власну ініціативу вирішення, спроби виправлень та свій роздум щодо того, що виглядає чи може бути неправильним.

Якщо у вашому браузері відображаються повідомлення про помилки, такі як "SyntaxError: незаконний символ", це насправді-пов'язаний, але а - синтаксична помилка .


Помилки синтаксису, що виникають у коді постачальника: Нарешті, врахуйте, що якщо помилка синтаксису не була підвищена редагуванням вашої кодової бази, але після встановлення або оновлення зовнішнього пакета постачальника, це може бути пов’язано з несумісністю версії PHP, тому перевіряйте вимоги постачальника щодо вашої платформи налаштування.


1
Цього недостатньо даних для відповіді, але можна написати аналізатор з parsekit_compile_string та поставити на нього більш дружні відповіді. Якщо інтегруватись у ваш IDE, це може бути досить інформативним.
Оуен Бересфорд

4
Ви вкладаєте в це вражаючу кількість роботи. Повага до цього. Мабуть, це дуже добре вчителям навчитися швидко вказувати на помилки або тим, хто створює IDE або впроваджує швидкі виправлення. Однак IDE вже ефективно виконає більшу частину цієї роботи за вас, як пропонує @Panique. До того ж, у багатьох випадках початок знову з нуля - хороший варіант.
allprog

1
@ Fred-ii- Я думаю, що більшість причин схожі на T_IF / T_FOREACH / ...блок. Хоча я хотів скласти більш спеціальний підсумок для питань IF / ELSE / ELSEIF.
Маріо

1
@mario Не знаю, як це сформулювати, але чи слід це питання трохи переписати та структурувати? (тимчасовий коментар)
Rizier123

2
Знаєте, я хотів би, щоб у мене був цей список, коли я вивчав PHP років тому. Дуже корисно, особливо для початківців.
Чіпстер,

Відповіді:


291

Які синтаксичні помилки?

PHP належить до мов програмування у стилі C та імперативу . Він має жорсткі правила граматики, які не може відновитись при зіткненні з неправильно розміщеними символами або ідентифікаторами. Він не може здогадатися про ваші наміри кодування.

Синтаксис визначення функції функції

Найважливіші поради

Існує кілька основних заходів, які ви завжди можете вжити:

  • Використовуйте належне відступ коду або прийняти будь-який високий стиль кодування. Читання читачів запобігає нерівностям.

  • Використовуйте IDE або редактор для PHP з підсвічуванням синтаксису . Що також допомагає в дужках / балансуванні дужок.

    Очікується: крапка з комою

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

Як інтерпретувати помилки парсера

Типове повідомлення про помилку синтаксису звучить:

Помилка розбору: помилка синтаксису, несподівана T_STRING , очікуючи ' ;' у file.php у рядку 217

У якому перераховано можливе розташування синтаксичної помилки. Дивіться згадане ім'я файлу та номер рядка .

Прізвище , такі якT_STRING пояснює , який символ аналізатора / токенізатор не зміг обробити остаточно. Однак це не обов'язково є причиною синтаксичної помилки.

Важливо вивчити попередні рядки коду . Часто синтаксичні помилки - це лише випадкові випадки, які траплялися раніше. Номер рядка помилки якраз там, де аналізатор остаточно відмовився обробити все це.

Вирішення синтаксичних помилок

Існує безліч підходів до звуження та виправлення синтаксичного гикавки.

  • Відкрийте згаданий вихідний файл. Подивіться на згаданий рядок коду .

    • Для втікаючих рядків і неправильних операторів зазвичай тут ви знайдете винуватця.

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

  • Більш регулярно потрібно також дивитися на попередні рядки .

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

    • Якщо {блоки коду }неправильно закриті або вкладені, можливо, вам доведеться ще більше дослідити вихідний код. Використовуйте належне відступ коду, щоб спростити це.

  • Подивіться на синтаксичну забарвлення !

    • Рядки та змінні та константи повинні мати різні кольори.

    • Оператори також +-*/.повинні бути тоніровані. Інакше вони можуть опинитися в неправильному контексті.

    • Якщо ви бачите, що колоритація рядків поширюється занадто далеко або занадто коротко, то ви знайшли немальований або відсутній маркер закриття "або 'рядка.

    • Наявність двох одноколірних знаків пунктуації поруч також може означати неприємності. Як правило, оператори одинаком , якщо це не ++, --або круглі дужки після оператора. Два рядки / ідентифікатори, що прямують один за одним, у більшості контекстів невірні.

  • Whitespace - твій друг . Дотримуйтесь будь-якого стилю кодування.

  • Тимчасово розбийте довгі лінії.

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

    • Розбийте складні ifзаяви на чіткі або вкладені ifумови.

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

    • Додати нові рядки між:

      1. Код, який ви можете легко визначити як правильний,
      2. Частини, про які ви не впевнені,
      3. І рядки, на які скаржаться аналізатор.

      Розбиття довгих блоків коду дійсно допомагає знайти походження помилок синтаксису.

  • Прокоментуйте код образи.

    • Якщо ви не можете ізолювати джерело проблеми, починайте коментувати (і тимчасово видаляти) блоки коду.

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

    • Іноді потрібно тимчасово видалити цілі блоки функцій / методів. (У випадку незрівнянних фігурних дужок і неправильно відрізаного коду.)

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

  • Як новачок уникайте деяких заплутаних синтаксичних конструкцій.

    • Оператор потрійних ? :умов може ущільнити код і справді корисний. Але це не допомагає читати у всіх випадках. Віддайте перевагу простим ifтвердженням, не перевернувши їх.

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

  • Найбільш поширені помилки новачків:

    • Пропущені крапки ;з комою для завершення операторів / рядків.

    • Невідповідні рядкові котирування для "або 'незмінені цитати всередині.

    • Забуті оператори, зокрема для .конкатенації рядків.

    • Незбалансовані (дужки ). Порахуйте їх у звітному рядку. Чи є їх однакова кількість?

  • Не забувайте, що розв’язання однієї синтаксичної проблеми може виявити наступну.

    • Якщо ви змусите одне питання вийти, а інше врізається в якийсь код нижче, ви в основному на правильному шляху.

    • Якщо після редагування нової синтаксичної помилки збирається в одному рядку, то ваша спроба зміни могла бути помилкою. (Не завжди.)

  • Відновіть резервну копію раніше працюючого коду, якщо ви не можете його виправити.

    • Прийняти систему версії вихідного коду. Ви завжди можете переглянути diffзламану та останню робочу версію. Що може бути освічуючим щодо проблеми синтаксису.
  • Невидимі символи бродячих Unicode : У деяких випадках у вашому джерелі потрібно використовувати шестигранник або інший редактор / переглядач. Деякі проблеми неможливо знайти, лише переглянувши свій код.

    • Спробуйте grep --color -P -n "\[\x80-\xFF\]" file.phpяк перший захід знайти символи, що не належать до ASCII.

    • Зокрема, BOM, пробіли нульової ширини або нерозривні пробіли, а також розумні цитати регулярно можуть знайти свій шлях до вихідного коду.

  • Подбайте про те, який тип рядкових рядків зберігається у файлах.

    • 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
Гео

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 )

2
Очевидно. Однак, перелічивши тут IDE, ви можете трохи розробити, де вони відрізняються між собою за синтаксисом? Sublime - це переважно редактор, а не IDE; але тоді більш гарненький і спритний; виконує в основному просто підсвічування синтаксису, але також справжнє при збігу дужок. Наприклад, він легко виявляє помилки T_CONSTANT_AND_ENCAPSED, на відміну від PHPStorm; яка, однак, робить більш чіткі лінії для вбудованих помилок. Підказки синтаксису NetBeans раніше були більш криптовалютними, ніж навіть PHP (скоріше відмічаючи дозволені конструкції). Чи можете ви поділитися своїм досвідом щодо плюсів / мінусів; ваш улюблений Eclipse / PDT чи ..?
mario

@mario Я думаю, ви справді заглиблені в цю тему, тому я дійсно не хочу сказати тут нічого поганого, але весь код, який я (і мої товариші по команді, друзі, які кодують, партнери-позаштатні) ніколи не писав у IDE, ніколи не був виконаний з синтаксичною помилкою. Тому я думаю, щонайменше перевірка синтаксису Netbeans / PHPStorm надзвичайно потужна. Але, можливо, я неправильно прочитав ваше запитання. Дай кілька годин ...;)
Sliq

Ваша відповідь уже на місці. Відповідає 99% наших запитань. Однак для контексту тут я хотів би розібратися з компромісом, на якому IDE надає більш зручні для новиків підказки . Для нас це, мабуть, незначно, якщо забарвлення і чіткі лінії є достатньою, якщо ви достатньо розбираєтесь. Але я припускаю, що відмінності можуть бути більш значущими для початківців.
Маріо

Іноді IDE не є можливим варіантом. Наприклад, внесення швидких змін до теми WordPress або плагіна. Так, я міг би скопіювати весь код в IDE, але потім мені доведеться відкрити його, вставити все там, встановити заголовки та все те, що інше витрачаєш лайно, коли я просто сподіваюся на швидке редагування. Тепер, якщо ви розробляєте нові функції або починаєте з нуля, то, так, зробіть це в IDE. Ви не пошкодуєте, що взяли цей додатковий час на початку, щоб налаштувати його.
1934286 р.

Я бачу IDE як трейлер, а не лише інструментарій. Він може не виправляти, але це може допомогти вам знайти та запобігти помилкам синтаксису. Багато відповідей тут, схоже, говорять про те, що якщо ви тримаєте код чистим, у вас є менше шансів помилитися і їх легше помітити. Добре з автоматичним відступом, підказками коду, появою змінних, автоматичним закриттям дужок та автоматичним форматуванням економить мені багато помилок на день і є основною перевагою, чому я використовую. Це не враховує все інше, що виходить за рамки цього питання (налагоджувач, роз'єм бази даних, 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як постійне ім'я.

    Якщо ви мали намір отримати доступ до змінної масиву (що є типовою причиною тут), тоді додайте провідну $sigil - так вона стане a $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 вище розірвано.
Danimal Reks

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. Відсутні дужки після мовних конструкцій

    Поспішне введення тексту може призвести до забутого дужки, що відкривається або закривається для ifта 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(...);

    Він досить поширений при запуску файлів і для копіювання та вставки коду. Перевірте у шестигранника, чи не відображається візуально ваш код із синтаксисом.

Дивись також


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. Але в подвійних цитованих рядках (або HEREDOC) це помилка. Аналізатор скаржиться на цитований сингл, який цитується '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 для використання трохи чіткого розмальовування для рядків з одним та подвійним цитуванням. (Це також допомагає з логікою програми віддати перевагу, наприклад, рядки з подвійним котируванням для текстового виведення, а рядки з цитованими одиночними цитатами лише для значень постійного типу.)

    Це хороший приклад, коли не слід вибиватися з подвійних лапок в першу чергу. Замість того, щоб просто використовувати власні \"пагони для HTML attributes 'цитати:

    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. Помилками рядків

    Ця синтаксична помилка найбільш часто зустрічається для неправильно вказаних рядкових значень. Будь-який без націлювання або відхилення "або 'цитата утворюватиме недійсний вираз:

                                     
     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”;

    Друкарські / розумні лапки - це символи Unicode. PHP розглядає їх як частину суміжного буквено-цифрового тексту. Наприклад ”these, інтерпретується як постійний ідентифікатор. Але будь-який наступний буквальний текст буде розглядатися парсером як головне / T_STRING.

  4. Відсутня крапка з комою; знову

    Якщо ви маєте незавершений вираз у попередніх рядках, то будь-який наступний вислів чи мовна конструкція сприймається як ідентифікатор необробленого:

           
    func1()
    function2();

    PHP просто не може знати, чи ви мали намір запускати дві функції за іншою, чи ви хотіли примножувати їх результати, додавати їх, порівнювати чи виконувати лише одну ||чи іншу.

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

    Це досить рідко. Але якщо увімкнено short_open_tags, ви не можете починати свої PHP-скрипти з декларацією XML :

          
    <?xml version="1.0"?>

    PHP побачить <?і поверне це для себе. Це не зрозуміє, для чого блукало xmlпризначене. Це буде трактовано як постійне. Але versionволя буде сприйматися як інша буквальна / константа. А оскільки аналізатор не може мати сенсу для двох наступних літералів / значень без оператора вираження між ними, це буде помилкою аналізатора.

  6. Невидимі символи Unicode

    Найбільш прикрими причинами синтаксичних помилок є символи Unicode, наприклад, нерозривний пробіл . PHP дозволяє символи Unicode в якості імен ідентифікаторів. Якщо ви отримаєте скаргу на аналізатор T_STRING на цілком підозрілий код, наприклад:

    <?php
        print 123;

    Вам потрібно вирвати ще один текстовий редактор. Або навіть гекседистором. Те, що виглядає тут як прості простори та нові рядки, може містити невидимі константи. Ідентифікатори IDE на основі Java іноді не звертають уваги на BT UTF-8, що перебуває у зануреному просторі, пробіли нульової ширини, роздільники абзаців тощо. Спробуйте переробити все, видаліть пробіл та додайте нормальні пробіли назад.

    Ви можете звузити його, додавши зайві ;роздільники операторів на кожному запуску рядка:

    <?php
        ;print 123;

    Додаткова ;крапка з комою перетворить попередній невидимий символ у невизначене постійне посилання (вираз у вигляді висловлювання). Що взамін змушує PHP видавати корисне повідомлення.

  7. Знак $ `відсутній перед іменами змінних

    Змінні в PHP представлені знаком долара, а потім іменем змінної.

    Знак долара ( $) - сигіл, який позначає ідентифікатор як ім'я змінної. Без цього sigil ідентифікатор може бути мовним ключовим словом або константою .

    Це поширена помилка, коли код PHP був "переведений" з коду, написаного іншою мовою (C, Java, JavaScript тощо). У таких випадках декларація типу змінної (коли початковий код був написаний мовою, яка використовує введені змінні), також може викрастись та призвести до цієї помилки.

  8. Уникнути лапки

    Якщо ви використовуєте \рядок, це має особливе значення. Це називається " Персонаж втечі " і, як правило, говорить парсеру буквально сприймати наступний символ.

    Приклад: 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. Попередьте як constant

    Для забутих змінних $префіксів у операторах керування ви побачите:

                           
    foreach ($array as wrong) {

    PHP тут іноді говорить вам, що очікували ::замість цього. Тому що змінна class :: $ могла б задовольнити очікуваний вираз $ змінної ..


Несподіване {

Фігурні дужки {та }додайте кодові блоки. І синтаксичні помилки щодо них зазвичай вказують на деяке неправильне вкладення.

  1. Неперевершені під вирази в if

    Найчастіше незбалансовані (і) є причиною, якщо аналізатор скаржиться на те, що відкриття фігурно {з’являється занадто рано. Простий приклад:

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

    Порахуйте свої дужки або скористайтеся IDE, що допомагає в цьому. Також не пишіть код без пробілів. Читання рахується.

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

    Ви не можете використовувати фігурні дужки у виразах. Якщо ви плутаєте круглі дужки та фігурні фігури, це не відповідає мові граматики:

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

    Існує кілька винятків для побудови ідентифікатора, наприклад, локальна змінна область ${references}.

  3. Змінні змінні або фігурні вирази 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 - моя проблема (на localhost (WAMP) все працює, але на linux webserver dont) була вирішена.
Едгарс Айварс

@EdgarsAivars Дякуємо за ваш коментар! Проблеми, пов'язані з платформою, справді є рідкісним і складним питанням. Я, мабуть, згадую це і тут. (Це було згадано вбік в іншій відповіді .)
Маріо

Я виявив, що отримати Unexpected} було тому, що частина мого коду використовувала короткий тег php <? замість <? php - знадобилося певний час, щоб знайти цей, як він працював на інших серверах.
c7borg

14

Несподіваний $ кінець

Коли PHP говорить про "несподіваний $end", це означає, що ваш код закінчився передчасно. (Повідомлення трохи оманливе, якщо сприймати його буквально. Мова не йде про змінну, яку називають "$ end", як іноді припускають новачки. Це стосується "кінця файлу" EOF,.)

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

Практично завжди йдеться про відсутність }фігурних дужок для закриття попередніх блоків коду.

  • Знову ж таки, використовуйте належні відступи, щоб уникнути подібних проблем.

  • Використовуйте IDE з відповідним дужкою, щоб дізнатися, де }це не так. У більшості IDE та текстових редакторів є комбінації клавіш:

    • NetBeans, PhpStorm, Komodo: Ctrl[іCtrl]
    • Eclipse, Аптана: CtrlShiftP
    • Atom, Sublime: Ctrlm- Zend StudioCtrlM
    • Geany, Блокнот ++: 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 продовжується до кінця файлу (звідси "Неочікуваний кінець $"). Майже всі IDE та редактори, що виділяють синтаксис, зроблять це очевидним або попереджають про це.

Уникнути лапки

Якщо ви використовуєте \рядок, це має особливе значення. Це називається " Персонаж втечі " і, як правило, говорить парсеру буквально сприймати наступний символ.

Приклад: 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вираз у виразі, такому як твердження для друку:

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

    Btw, останній рядок у {…}кодовому блоці також потребує крапки з комою.

  4. Точка з комою занадто рано

    Зараз, мабуть, неправильно звинувачувати певний стиль кодування, оскільки цей підводний камінь занадто легко не помітити:

                
    if ($x == 5);
    {
        $y = 7;
    }
    else           
    {
        $x = -1;    
    }

    Що трапляється частіше, ніж ви могли собі уявити.

    • Коли ви припините if ()вираз з; ним, буде виконано недійсне твердження. Це ;стає порожнім {}власним!
    • Таким {…}чином, блок відривається від 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. Інше / Ельсейф у неправильному порядку

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

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

    Ви можете мати скільки elseifзавгодно s, але 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 } ?>

    Це більш-менш варіація неправильного відступу - імовірно, часто заснована на неправильних намірах кодування.
    Ви не можете перемішувати інші оператори між 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 термінатор.

    У той час як "несподіваний $-кінець", як правило, ціна на забуту }фігурну фігурну дужку.

  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.

    Це насправді більше випадків виразів у чорному списку (через еквівалентну асоціативність оператора). Він синтаксично дійсний у кількох мовах стилю С, але і 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

Несподіваний "?", Очікуючи змінну

Схожа помилка може виникнути для змінних типів, як у:

function add(?int $sum): ?int {

Що знову вказує на застарілу версію PHP, що використовується (або версія CLI, php -vабо версія, пов’язана з веб-сервером phpinfo();).


5

Несподіваний T_LNUMBER

Маркер T_LNUMBERпозначає "довге" / число.

  1. Недійсні імена змінних

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

    $1   // Bad
    $_1  // Good

    *

    • Досить часто трапляється використовувати preg_replace-placeholders "$1"в контексті PHP:

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

      Там, де повинен був бути вказаний зворотний дзвінок. (Зараз /eпрапор регулярного вираження застарілий. Але іноді він все ще не використовується в preg_replace_callbackфункціях.)

    • Це ж обмеження ідентифікатора стосується властивостей об'єкта , btw.

             
      $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є твердженням (як для, або якщо) і повинно бути окремим. Його не можна використовувати як частину виразу. Частково тому, що продовження не повертає значення, але в виразі кожен суб-вираз повинен призводити до деякого значення, тому загальний вираз призводить до значення. Ось різниця між твердженням і виразом.

Це означає, що 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 ви можете використовувати його для виразів масиву .

$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.gether.php


0

Повідомлення про помилку, яке починається, Parse error: syntax error, unexpected ':'може бути викликане помилковим написанням статичної посилання класу Class::$Variableяк Class:$Variable.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.