Отладка пустых страниц: поиск и исправление скрытых ошибок PHP
Основные причины пустой страницы и универсальное решение
Пустая страница в PHP (так называемый «белый экран смерти») возникает, когда скрипт завершается с фатальной ошибкой, но вывод ошибок отключен. Самое эффективное первое действие – включить отображение всех ошибок на время отладки. Для этого в начало скрипта (или в конфигурационный файл) добавляются следующие строки:
error_reporting(E_ALL);
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);Php пустая страница (пустая страница в php)
После этого страница перестанет быть пустой – на ней появится сообщение об ошибке с указанием файла и строки. Если ошибка не появилась, проверьте логи веб-сервера (например, error.log Apache) или системный лог PHP. Также выполните синтаксическую проверку файла из командной строки:
php -l script.php
Важно:
- На рабочем сервере display_errors должен быть выключен (установлен в 0), чтобы не раскрывать чувствительную информацию. Вместо этого используйте логирование.
- Если пустая страница появляется при загрузке большого скрипта, увеличьте лимит памяти:
ini_set('memory_limit', '256M');. - Проверьте, нет ли вывода до вызова
header()– используйте буферизациюob_start().
Типичная ошибка:
Даже после включения display_errors страница остаётся пустой. Причина – фатальная ошибка в файле, который подключается раньше, чем выполняется код с настройками. Решение: поместите настройки в начало самого первого выполняемого файла (обычно index.php) или через файл .user.ini / .htaccess.
Как найти причину, если display_errors не помогает?
Если ошибка не отображается, проверьте логи PHP. Настройте путь к логу в php.ini или в скрипте:
ini_set('error_log', '/var/log/php_errors.log');
ini_set('log_errors', 1);
Выполните скрипт и откройте лог. Также можно использовать error_get_last() в конце скрипта для получения последней ошибки.
Проблема:
Лог пуст – возможно, ошибка происходит до выполнения вашего кода (например, в подключаемом файле с синтаксической ошибкой). В этом случае проверьте файл синтаксически через php -l.
Как отловить фатальные ошибки, чтобы показать пользователю понятное сообщение?
Используйте register_shutdown_function вместе с error_get_last(). Это позволит перехватить фатальные ошибки (E_ERROR, E_PARSE и т.д.) и вывести собственное сообщение.
register_shutdown_function(function() {
$error = error_get_last();
if ($error && in_array($error['type'], [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR])) {
echo "Извините, произошла внутренняя ошибка. Мы уже работаем над ней.";
// Дополнительно записать ошибку в лог
error_log($error['message']);
}
});
Ограничение:
register_shutdown_function не перехватывает ошибки парсинга, если сам файл содержит синтаксическую ошибку. Для таких случаев используйте проверку через php -l перед выполнением.
Как проверить, что проблема именно в include или require?
Некорректный путь к файлу или ошибка внутри подключаемого файла часто приводят к пустой странице. Проверьте возвращаемое значение include и используйте require_once для критичных файлов.
$result = include 'config.php';
if ($result === false) {
die('Ошибка подключения файла config.php');
}
Для проверки существования файла перед подключением:
$file = 'config.php';
if (file_exists($file)) {
require_once $file;
} else {
echo "Файл $file не найден";
}
Типичная ошибка:
Относительные пути работают не так, как ожидается. Используйте __DIR__ для задания абсолютного пути.
require_once __DIR__ . '/config.php';
Что делать, если пустая страница появляется после перенаправления header('Location: ...')?
Проблема часто возникает из-за вывода какого-либо текста до вызова header(). Даже один пробел перед открывающим тегом <?php может вызвать ошибку. Используйте буферизацию вывода.
ob_start();
// ... какой-то код ...
header('Location: /new-page');
ob_end_flush();
Также убедитесь, что файл сохранён без BOM (Byte Order Mark).
Типичная ошибка:
Использование exit после header не решает проблему вывода до вызова. Всегда ставьте ob_start() в самом начале скрипта.
Как проверить синтаксис всех файлов проекта сразу?
Для больших проектов выполните команду в терминале (Linux/macOS):
find . -name '*.php' -exec php -l {} \;
На Windows используйте PowerShell:
Get-ChildItem -Recurse -Filter *.php | ForEach-Object { php -l $_.FullName }
Если какой-то файл содержит синтаксическую ошибку – команда выведет сообщение об ошибке и путь.
Примечание:
Этот метод не выявит ошибки времени выполнения, только синтаксические.
Дополнительные источники пустой страницы:
- Превышение лимита времени выполнения (
max_execution_time) – увеличьте черезini_set(). - Ошибка в файле конфигурации веб-сервера (например,
.htaccessс неверными директивами). - Бесконечный цикл или рекурсия – добавьте отладочный вывод.
- Проблемы с кодировкой файла (BOM) – используйте редактор без BOM.
Расширенные примеры отладки пустой страницы в PHP
Пример 1. Перехват всех ошибок через set_error_handler и исключения
set_error_handler(function($severity, $message, $file, $line) {
throw new ErrorException($message, 0, $severity, $file, $line);
});
try {
// Потенциально опасный код
include 'nonexistent_file.php';
} catch (ErrorException $e) {
echo "Ошибка: " . $e->getMessage() . " в файле " . $e->getFile() . " на строке " . $e->getLine();
}
Ошибка: include(nonexistent_file.php): failed to open stream: No such file or directory в файле /var/www/index.php на строке 7
Пояснение:
Преобразует все нефатальные ошибки в исключения, которые можно отловить. Фатальные ошибки (E_ERROR) таким способом не перехватываются, для них нужен register_shutdown_function.
Пример 2. Кастомная страница ошибки с регистрацией shutdown
function customShutdown() {
$error = error_get_last();
if ($error && ($error['type'] & (E_ERROR | E_PARSE | E_CORE_ERROR | E_COMPILE_ERROR))) {
// Логируем ошибку
file_put_contents('/tmp/php_errors.log', date('Y-m-d H:i:s') . ' ' . $error['message'] . PHP_EOL, FILE_APPEND);
// Выводим дружественное сообщение
header('HTTP/1.1 500 Internal Server Error');
echo '<!DOCTYPE html><html><head><title>Ошибка сервера</title></head><body><h1>500 Внутренняя ошибка сервера</h1><p>Пожалуйста, попробуйте позже.</p></body></html>';
}
}
register_shutdown_function('customShutdown');
// Намеренная фатальная ошибка
call_to_undefined_function();
Выводит HTML-страницу с сообщением 500, а в лог записывается ошибка.
Пример 3. Буферизация вывода для отлова вывода до header
ob_start();
function redirect($url) {
ob_clean(); // очищаем буфер, если был вывод
header('Location: ' . $url);
exit;
}
// Пример нежелательного вывода
echo "Пробел";
redirect('/new-page');
При выполнении скрипта произойдет редирект, так как буфер был очищен. Если убрать ob_clean(), вы получите предупреждение о том, что заголовки уже отправлены.
Пример 4. Проверка файлов на синтаксис через PHP-скрипт
$directory = __DIR__;
$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory));
$errors = [];
foreach ($iterator as $file) {
if ($file->getExtension() === 'php') {
$output = shell_exec('php -l ' . escapeshellarg($file->getPathname()) . ' 2>&1');
if (strpos($output, 'No syntax errors') === false) {
$errors[] = $output;
}
}
}
if (!empty($errors)) {
echo "Найдены синтаксические ошибки:\n";
foreach ($errors as $error) {
echo $error . "\n";
}
} else {
echo "Синтаксических ошибок не найдено.";
}
Выводит сообщение об ошибке или об успешной проверке.
Пример 5. Использование Xdebug для трассировки
// В php.ini:
zend_extension=xdebug.so
xdebug.mode=develop,debug
xdebug.start_with_request=yes
// В скрипте:
function test($a, $b) {
return $a / $b;
}
echo test(10, 0); // Ошибка деления на ноль
Xdebug выведет цветной стек вызовов с указанием файла и строки, где произошла ошибка. Это помогает быстро найти причину пустой страницы.