Перейти к содержимому
Теория · Первая программа · урок 3 из 7

Ошибки в программе

В прошлом уроке PHP не запустил файл из-за пропущенной запятой. Вернёмся к повару с карточкой рецепта: работа у него может пойти не так по трём разным причинам.

  • Страница порвана, и рецепт не прочитать. Повар не начинает готовить вовсе.
  • Повар дошёл до шага «добавьте шафран», а шафрана на кухне нет. Шаги до этого сделаны, а дальше работа встаёт.
  • В шаге написано «2 ложки соли или около того». Повар кладёт 2 ложки, оставляет на полях пометку и готовит дальше.

У PHP есть ошибки всех трёх видов, и первое слово его сообщения называет вид. Давайте разберём каждый по очереди.

Три вида ошибок

Ошибка разбора

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

PHP
<?php

echo "One\n";
echo "Two\n";
echo "Three\n" // ✗
TEXT
Parse error: syntax error, unexpected end of file, expecting "," or ";"

Ошибка стоит в последней строке, но не напечатано даже One. PHP нашёл её ещё при разборе, до запуска. Слова unexpected end of file значат «неожиданный конец файла»: PHP ждал запятую или точку с запятой, а файл кончился.

Фатальная ошибка

Фатальная ошибка случается во время работы программы: PHP доходит до строки и не может её выполнить. Строки выше уже выполнились, а строки ниже не выполнятся:

PHP
<?php

echo "Hi\n"; // Hi
echo Hello, "\n"; // ✗
echo "Bye\n";
TEXT
Fatal error: Uncaught Error: Undefined constant "Hello"

У слова Hello нет кавычек. Там, где echo ждёт значение, PHP считает слово без кавычек именем константы, то есть значения, которое программа должна объявить заранее. Такая запись не нарушает правил языка, поэтому разбор проходит, и программа печатает Hi.

На строке с Hello PHP ищет такую константу, не находит её и останавливает программу. Слова Undefined constant значат «неизвестная константа», а Bye так и не напечатано.

Здесь картинка с поваром перестаёт работать. Настоящий повар нашёл бы замену шафрану или пропустил шаг, а PHP на такой строке замену не ищет и останавливается.

Предупреждение

Предупреждение — сообщение о том, что в строке что-то не так, но PHP смог её выполнить. После предупреждения программа идёт дальше:

PHP
<?php

echo "One\n"; // One
echo "5 apples" + 1, "\n"; // ✗
echo "Three\n"; // Three
TEXT
Warning: A non-numeric value encountered

Разберём, что произошло:

  1. Первая строка печатает One.
  2. Во второй строке + складывает текст с числом. PHP берёт 5 из начала текста "5 apples" и печатает 6, но перед этим выводит предупреждение: «встретилось нечисловое значение».
  3. Третья строка выполняется как обычно и печатает Three.

Предупреждение PHP печатает прямо в вывод, между строками программы. Результат 6 может оказаться не тем, чего вы ждали, поэтому читайте и исправляйте предупреждения.

Как отличить по выводу

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

  • Parse error и пустой вывод — ошибка разбора: файл не запускался;
  • Fatal error, строки выше напечатаны, а ниже нет — фатальная ошибка: программа остановилась на этой строке;
  • Warning и все строки напечатаны — предупреждение: программа сообщила о проблеме и выполнилась до конца.

Как читать сообщение

Сообщение PHP складывается из частей:

  1. В начале — вид ошибки: Parse error, Fatal error или Warning.
  2. После двоеточия — описание: что именно не так.
  3. В конце первой строки — путь к файлу и номер строки: in /home/anna/hello.php on line 4, а у фатальной ошибки короче — in /home/anna/hello.php:4.
  4. После фатальной ошибки идут ещё строки Stack trace: и thrown in. В первых программах их можно не читать.

Слова Uncaught Error в фатальной ошибке значат «непойманная ошибка»: PHP сообщил об ошибке, программа её не обработала и поэтому остановилась. В уроках курса от сообщения остаётся первая строка без пути и номера строки, как в примерах выше.

Частая ошибка

Ошибку ищут на строке, которую назвал PHP, а она стоит выше:

PHP
<?php

echo "One\n";
echo "Two\n" // ✗
echo "Three\n";
TEXT
Parse error: syntax error, unexpected token "echo", expecting "," or ";"

В конце полного сообщения PHP пишет on line 5, хотя в строке 5 всё верно. Точку с запятой забыли в конце строки 4. PHP заметил это, только когда встретил следующий echo: там он ждал , или ;. Если строка из сообщения выглядит правильной, проверьте конец строки над ней.

Главное

  • Ошибку разбора PHP находит до запуска, поэтому не выполняется ни одна строка.
  • Фатальная ошибка останавливает программу на своей строке: строки выше уже выполнились, а ниже — нет.
  • После предупреждения Warning программа продолжает работу.
  • Первое слово сообщения называет вид ошибки, а пропущенную ; ищите в конце строки над той, которую назвал PHP.