PHP белый экран смерти

Теперь, когда я начинаю возвращаться к PHP, я начинаю вспоминать, почему я вообще отказался от него. Самая досадная вещь на моей тарелке на данный момент - это то, что я назвал "белым экраном смерти PHP". Когда PHP получает фатальную ошибку из-за синтаксиса или чего-то еще, кажется, что он всегда умрет без фактической отправки чего-либо в браузер. Я добавил следующее к моему .htaccessи, кажется, работает большую часть времени, но в этих случаях это не работает.

php_value display_errors 1
php_value display_startup_errors 1
php_value error_reporting 2147483647 # E_ALL

Я что-то пропустил? В данный момент я чувствую, что мне нужно нажать обновить все несколько строк кода, которые я пишу, чтобы я не совершил ошибку и не перебрал множество страниц, пытаясь отследить ту маленькую ошибку, которую я сделал...

РЕДАКТИРОВАТЬ: Например, учитывая две строки кода ниже:

$foo = array(':language' => $languageId;
$foo = array(':language' => $languageId);

Первый будет отображать белый экран смерти (т. Е. Вообще ничего не печатать в браузере), а второй будет работать счастливо.

15 ответов

Решение

Ошибки и предупреждения обычно появляются в ....\logs\php_error.log или же ....\logs\apache_error.log в зависимости от ваших настроек php.ini.

Также полезные ошибки часто направлены в браузер, но, поскольку они не являются действительными html, они не отображаются.

Так "tail -f"Ваши файлы журналов и когда вы получаете пустой экран, используйте IE, меню"view" -> "source"для просмотра необработанного вывода.

Следующий код должен отображать все ошибки:

<?php

// ----------------------------------------------------------------------------------------------------
// - Display Errors
// ----------------------------------------------------------------------------------------------------
ini_set('display_errors', 'On');
ini_set('html_errors', 0);

// ----------------------------------------------------------------------------------------------------
// - Error Reporting
// ----------------------------------------------------------------------------------------------------
error_reporting(-1);

// ----------------------------------------------------------------------------------------------------
// - Shutdown Handler
// ----------------------------------------------------------------------------------------------------
function ShutdownHandler()
{
    if(@is_array($error = @error_get_last()))
    {
        return(@call_user_func_array('ErrorHandler', $error));
    };

    return(TRUE);
};

register_shutdown_function('ShutdownHandler');

// ----------------------------------------------------------------------------------------------------
// - Error Handler
// ----------------------------------------------------------------------------------------------------
function ErrorHandler($type, $message, $file, $line)
{
    $_ERRORS = Array(
        0x0001 => 'E_ERROR',
        0x0002 => 'E_WARNING',
        0x0004 => 'E_PARSE',
        0x0008 => 'E_NOTICE',
        0x0010 => 'E_CORE_ERROR',
        0x0020 => 'E_CORE_WARNING',
        0x0040 => 'E_COMPILE_ERROR',
        0x0080 => 'E_COMPILE_WARNING',
        0x0100 => 'E_USER_ERROR',
        0x0200 => 'E_USER_WARNING',
        0x0400 => 'E_USER_NOTICE',
        0x0800 => 'E_STRICT',
        0x1000 => 'E_RECOVERABLE_ERROR',
        0x2000 => 'E_DEPRECATED',
        0x4000 => 'E_USER_DEPRECATED'
    );

    if(!@is_string($name = @array_search($type, @array_flip($_ERRORS))))
    {
        $name = 'E_UNKNOWN';
    };

    return(print(@sprintf("%s Error in file \xBB%s\xAB at line %d: %s\n", $name, @basename($file), $line, $message)));
};

$old_error_handler = set_error_handler("ErrorHandler");

// other php code

?>

Единственный способ создать пустую страницу с этим кодом - это когда у вас есть ошибка в обработчике завершения работы. Я скопировал и вставил это из моей собственной CMS без тестирования, но я уверен, что это работает.

Я всегда использую этот синтаксис в самом верху скрипта php.

ini_set('error_reporting', E_ALL);
ini_set('display_errors', 'On');  //On or Off

Можно зарегистрировать ловушку, чтобы сделать видимой последнюю ошибку или предупреждение.

function shutdown(){
  var_dump(error_get_last());
}

register_shutdown_function('shutdown');

добавление этого кода в начало вашего index.php поможет вам отладить проблемы.

Это проблема загрузки и конфигурации во время выполнения

Важно понимать, что синтаксическая ошибка или ошибка синтаксического анализа происходят во время этапа компиляции или синтаксического анализа, что означает, что PHP будет запускаться еще до того, как у него появится возможность выполнить любой ваш код. Так что, если вы модифицируете PHP display_errors конфигурация во время выполнения (это включает в себя что-либо от использования ini_set в вашем коде для использования.htaccess, который является файлом конфигурации времени выполнения), тогда будут использоваться только загруженные по умолчанию параметры конфигурации.

Как всегда избегать WSOD в разработке

Чтобы избежать WSOD, вы должны убедиться, что ваш загруженный файл конфигурации имеет display_errors на и error_reporting установлен в -1 (это эквивалент E_ALL, потому что он гарантирует, что все биты включены независимо от того, какую версию PHP вы используете). Не задавайте жестко постоянное значение E_ALL, потому что это значение может изменяться в разных версиях PHP.

Загруженная конфигурация является либо вашей загруженной php.ini файл или ваш apache.conf или же httpd.conf или файл виртуального хоста. Эти файлы читаются только один раз на этапе запуска (например, при первом запуске apache httpd или php-fpm) и переопределяются только изменениями конфигурации среды выполнения. Убедившись, что display_errors = 1 а также error_reporting = -1 в загруженном файле конфигурации гарантирует, что вы никогда не увидите WSOD независимо от синтаксиса или ошибки синтаксического анализа, которые происходят до изменения времени выполнения, например ini_set('display_errors', 1); или же error_reporting(E_ALL); может иметь место

Как найти ваши (php.ini) загруженные файлы конфигурации

Чтобы найти загруженные файлы конфигурации, просто создайте новый файл PHP только со следующим кодом...

<?php
phpinfo();

Затем направьте туда свой браузер и посмотрите на проанализированный загруженный файл конфигурации и дополнительные файлы.ini, которые обычно находятся вверху вашего phpinfo() и будет включать в себя абсолютный путь ко всем загруженным файлам конфигурации.

Если ты видишь (none) вместо файла это означает, что у вас нет php.ini в пути к файлу конфигурации (php.ini). Поэтому вы можете скачать отсюда php.ini, поставляемый в комплекте с PHP, и скопировать его в путь к файлу конфигурации как php.ini, а затем убедиться, что у вашего пользователя php достаточно прав для чтения из этого файла. Вам нужно будет перезапустить httpd или php-fpm, чтобы загрузить его. Помните, что это файл разработки php.ini, который поставляется в комплекте с исходным кодом PHP. Поэтому, пожалуйста, не используйте его в производстве!


Только не делай этого в производстве

Это действительно лучший способ избежать WSOD в разработке. Тот, кто предлагает, чтобы вы положили ini_set('display_errors', 1); или же error_reporting(E_ALL); в верхней части вашего скрипта PHP или использование.htaccess, как вы это сделали здесь, не поможет вам избежать WSOD, когда возникает ошибка синтаксиса или разбора (как в вашем случае здесь), если ваш загруженный файл конфигурации имеет display_errors выключен.

Многие люди (и стандартные установки PHP) будут использовать производственный INI-файл, который имеет display_errors по умолчанию отключено, что обычно приводит к тому же разочарованию, которое вы испытали здесь. Поскольку PHP уже отключил его при запуске, он сталкивается с синтаксической ошибкой или ошибкой синтаксического анализа и не выдает ничего. Вы ожидаете, что ваш ini_set('display_errors',1); в начале вашего PHP-скрипта следовало бы этого избежать, но не имеет значения, если PHP не сможет проанализировать ваш код, потому что он никогда не достигнет времени выполнения.

Не знаю, поможет ли это, но вот часть моего стандартного конфигурационного файла для проектов php. Я склонен не слишком сильно зависеть от настроек apache даже на моем собственном сервере.

У меня никогда не было проблемы с исчезающей ошибкой, поэтому, возможно, что-то здесь даст вам представление.

Отредактировано, чтобы показать APPLICATON_LIVE

/*
APPLICATION_LIVE will be used in process to tell if we are in a development or production environment.  It's generally set as early as possible (often the first code to run), before any config, url routing, etc.
*/

if ( preg_match( "%^(www.)?livedomain.com$%", $_SERVER["HTTP_HOST"]) ) {
    define('APPLICATION_LIVE', true);
} elseif ( preg_match( "%^(www.)?devdomain.net$%", $_SERVER["HTTP_HOST"]) ) {
    define('APPLICATION_LIVE', false);
} else {
    die("INVALID HOST REQUEST (".$_SERVER["HTTP_HOST"].")");
    // Log or take other appropriate action.
}


/*
--------------------------------------------------------------------
DEFAULT ERROR HANDLING
--------------------------------------------------------------------
Default error logging.  Some of these may be changed later based on APPLICATION_LIVE.
*/
error_reporting(E_ALL & ~E_STRICT);
ini_set ( "display_errors", "0");
ini_set ( "display_startup_errors", "0");
ini_set ( "log_errors", 1);
ini_set ( "log_errors_max_len", 0);
ini_set ( "error_log", APPLICATION_ROOT."logs/php_error_log.txt");
ini_set ( "display_errors", "0");
ini_set ( "display_startup_errors", "0");

if ( ! APPLICATION_LIVE ) {
    // A few changes to error handling for development.
    // We will want errors to be visible during development.
    ini_set ( "display_errors", "1");
    ini_set ( "display_startup_errors", "1");
    ini_set ( "html_errors", "1");
    ini_set ( "docref_root", "http://www.php.net/");
    ini_set ( "error_prepend_string", "<div style='color:red; font-family:verdana; border:1px solid red; padding:5px;'>");
    ini_set ( "error_append_string", "</div>");
}

Откройте свой php.ini, убедитесь, что он установлен на:

display_errors = On

перезагрузите ваш сервер.

Для тех, кто использует nginx и имеет белый экран даже для файла с <?php echo 123;, В моем случае у меня не было этой обязательной опции для PHP в конфигурационном файле nginx:

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

Эта опция отсутствовала в файле fastcgi_params, поэтому PHP не работал и в логах не было ошибок.

Попробуйте установить уровень сообщений об ошибках в ваших фактических файлах php. Или, как другие предложили, проверьте настройки вашего сервера - это может быть что-то в php.ini или какое-то ограничение в отношении вашего хоста. Не полагайтесь только на.htaccess. Кроме того, при устранении неполадок, print_r любые переменные, которые могут показаться подозрительными

Вы уверены, что PHP на самом делеdisplay_errors'установка из.htaccess? Проверьте вывод phpinfo() Функция, чтобы убедиться.

Кроме того, вы должны проверить, чтобы убедиться, что вы не использовали@', это может заставить замолчать ваши ошибки, если вы использовали' @include... 'или' @some_function (...) ', где-то вверх по трассировке стека.

Некоторые приложения сами обрабатывают эти инструкции, вызывая что-то вроде этого:

error_reporting(E_ALL & ~E_DEPRECATED); or error_reporting(0);

И, таким образом, переопределяя ваши настройки.htaccess.

Я также видел такие ошибки, когда fastcgi_params или же fastcgi.conf Конфигурационный файл неправильно включен в конфигурацию сервера. Так что исправление для меня было глупым:

include /etc/nginx/fastcgi_params;

Мне потребовался час, чтобы выяснить это...

С помощью @inexistent_function_call(); в вашем коде заставит интерпретатора спокойно умереть и прервать разбор скрипта. Вам следует проверить наличие недействительных функций и не использовать оператор подавления ошибок (@ char)

Вы также можете запустить файл в Терминале (командной строке) следующим образом: php -f filename.php,

Это запускает ваш код и дает вам тот же вывод в случае любых ошибок, которые вы увидите в error.log, Здесь упоминается ошибка и номер строки.

Если ошибка в коде PHP, вы можете использовать функцию error_reporting() в вашем коде, чтобы установить для отчета все.

Однако это не обрабатывает ситуацию, когда происходит сбой PHP. Информация об этом доступна только в логах сервера. Возможно, у вас нет доступа к ним, но многие хостинг-провайдеры, с которыми я работал, имеют какой-то способ предоставить вам доступ к нему. Например, подход, который мне нравится больше всего, заключается в том, что он создает файл error_log в текущем каталоге, где находится.php. Попробуйте поиск там или свяжитесь с вашим хостинг-провайдером по этому поводу.

Другие вопросы по тегам