Отладка пустых страниц: поиск и исправление скрытых ошибок PHP

Раздел: Обработка ошибок 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 выведет цветной стек вызовов с указанием файла и строки, где произошла ошибка. Это помогает быстро найти причину пустой страницы.

Пустая страница в PHP - comments

En
Php пустая страница (php)