Диагностика и исправление parse error в PHP
Ошибка парсинга PHP (parse error) возникает, когда интерпретатор обнаруживает синтаксическую некорректность в исходном коде. Такая ошибка делает выполнение скрипта невозможным. Большинство случаев связано с пропущенными точками с запятой, несогласованными фигурными скобками, неправильными кавычками или проблемами с кодировкой. Ниже рассмотрены основные причины и способы их устранения.
Основные причины и поиск ошибки
Как быстро определить строку, в которой произошла синтаксическая ошибка?
Наиболее эффективное решение - включить отображение всех ошибок PHP и использовать встроенный синтаксический анализатор.
php -l file.php
Команда php -l (lint) проверяет файл на синтаксические ошибки без его выполнения. Вывод содержит номер строки и описание проблемы. Например:
Parse error: syntax error, unexpected ';' in /path/to/file.php on line 42
Для включения отображения ошибок в самом скрипте используется следующий код в начале файла:
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
?>
Проблема: Если display_errors отключён в конфигурации сервера, ошибки не выводятся. Тогда необходимо проверить файл php.ini или использовать php -l в командной строке.
Как исправить пропущенную точку с запятой?
Пропущенный символ ; в конце инструкции - одна из самых частых причин parse error. Пример ошибочного кода:
<?php
echo "Привет"
$name = "Мир";
?>
Интерпретатор сообщит об ошибке на следующей строке после пропущенного символа. Исправление - добавить точку с запятой после echo "Привет";.
Проблема: Иногда ошибка проявляется как unexpected end of file, если точка с запятой пропущена в самом конце скрипта. Решение - проверить последнюю инструкцию.
Как исправить несогласованные фигурные скобки?
Незакрытые или лишние фигурные скобки в блоках if, foreach, function. Пример ошибки:
<?php
if ($a) {
echo "a";
} else {
echo "b";
// закрывающая скобка отсутствует
?>
Исправление - добавить недостающую } в конце блока else.
Проблема: Ошибка unexpected '}' возникает, когда закрывающая скобка не соответствует ни одному открывающему блоку. Рекомендуется использовать отступы для визуального контроля парности скобок.
Как исправить неправильные кавычки и строки?
Неправильное экранирование или смешивание одинарных и двойных кавычек внутри строк. Особенно часто встречается в heredoc-синтаксисе. Пример ошибочного heredoc:
<?php
echo <<<EOT
Привет, мир
EOT;
// неверный отступ закрывающего идентификатора
?>
Закрывающий идентификатор EOT; должен находиться на отдельной строке, без предшествующих пробелов или табуляции. Исправление - удалить пробелы перед EOT;.
Проблема: Ошибка unexpected T_STRING часто указывает на некорректные символы внутри строки. Проверяйте экранирование кавычек и символы Юникода.
Как исправить проблемы с кодировкой (BOM)?
Файлы, сохранённые с UTF-8 BOM (Byte Order Mark), могут вызывать parse error, так как BOM - это невидимый символ в начале файла. Это приводит к ошибке Unexpected character in input. Решение - сохранять файлы без BOM (в кодировке UTF-8 without BOM).
// Используйте редактор (например, VS Code) и выберите кодировку UTF-8 без BOM.
Проблема: Некоторые редакторы по умолчанию добавляют BOM. После сохранения с BOM скрипт перестаёт работать. Проверить наличие BOM можно с помощью hex-редактора или PHP-функции bin2hex(file_get_contents('file.php')).
Как исправить использование коротких тегов?
Если файл использует короткие теги <? ... ?> вместо <?php ... ?>, а в конфигурации сервера отключена директива short_open_tag, возникает parse error. Решение - заменить все короткие теги на полные, либо включить short_open_tag = On в php.ini.
// Неправильно:
<? echo "Привет"; ?>
// Правильно:
<?php echo "Привет"; ?>
Проблема: Использование <?= (короткий echo) разрешено с PHP 5.4 и выше независимо от short_open_tag. Однако старые версии могут требовать его включения.
Ниже приведены расширенные примеры синтаксических ошибок и способы их отладки.
Примеры с подробным кодом и выводом
Пример 1: Многострочная строка с неправильным закрывающим символом
<?php
$text = <<<EOT
Это текст
с несколькими
строками.
EOT;
// Здесь закрывающий идентификатор EOT имеет лишний пробел в начале
?>
Вывод php -l:
Parse error: syntax error, unexpected end of file in /path/to/file.php on line 7
Исправление - удалить пробел перед EOT;.
Пример 2: Вложенные циклы с пропущенной фигурной скобкой
<?php
for ($i = 0; $i < 3; $i++) {
for ($j = 0; $j < 3; $j++) {
echo $i * $j . " ";
}
// пропущена закрывающая скобка внешнего цикла
?>
Parse error: syntax error, unexpected '?>' in /path/to/file.php on line 8
Добавить } перед ?>.
Пример 3: Использование error_reporting и display_errors для отладки
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
function test() {
echo "Вызов функции";
} // забыли точку с запятой после объявления?
test();
?>
При запуске скрипта будет выведено сообщение об ошибке с номером строки. Вывод:
Parse error: syntax error, unexpected 'test' (T_STRING) in /path/to/file.php on line 8
Ошибка возникает из-за пропущенной точки с запятой после закрывающей скобки функции? На самом деле в данном примере ошибка в другой строке - после объявления функции не требуется точка с запятой. Правильный код:
function test() {
echo "Вызов функции";
}
test();
?>
Пример 4: Отладка через лог-файл
<?php
ini_set('log_errors', 1);
ini_set('error_log', '/tmp/php_errors.log');
$data = array(
'key1' => 'val1',
'key2' => 'val2', // лишняя запятая - допустимо в PHP 7.2+?
);
?>
В этом примере синтаксической ошибки нет (разрешена висячая запятая). Однако при наличии реальной ошибки сообщение будет записано в лог. Пример вывода лога при ошибке парсинга:
[14-Mar-2025 10:00:00 UTC] PHP Parse error: syntax error, unexpected ';' in /path/to/file.php on line 5
Пример 5: Проблема с кодировкой - скрытый BOM
// file.php сохранён с UTF-8 BOM
<?php
header('Content-Type: text/plain');
echo 'Hello';
?>
Вывод при запуске:
Parse error: syntax error, unexpected '?>' in /path/to/file.php on line 1
Решение - пересохранить файл без BOM. Проверить наличие BOM можно так:
$ php -r 'echo bin2hex(file_get_contents("file.php"));'
Если первые 3 байта - EF BB BF, то BOM присутствует.