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);

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

Ответы

Ответ 1

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

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

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

Ответ 2

В следующем коде должны отображаться все ошибки:

<?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([email protected]_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 без тестирования, но я уверен, что он работает.

Ответ 3

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

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

Ответ 4

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

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

register_shutdown_function('shutdown');

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

Ответ 5

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

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

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

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

Загруженная конфигурация - это либо ваш загруженный файл php.ini, либо ваш файл apache.conf или httpd.conf или virtualhost. Эти файлы читаются только один раз на этапе запуска (когда вы сначала запускаете 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) будут использовать файл production-ini, который по умолчанию отключен display_errors, что обычно приводит к тому же разочарованию, которое вы испытали здесь. Поскольку PHP уже отключился, когда он запускается, он сталкивается с синтаксической или синтаксической ошибкой и не дает ничего для вывода. Вы ожидаете, что ваш ini_set('display_errors',1); в верхней части вашего PHP скрипт должен был избежать этого, но не имеет значения, не может ли PHP не разобрать ваш код, потому что он никогда не достигнет среды выполнения.

Ответ 6

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

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

Отредактировано для отображения APPLICATON_LIVE

/*
APPLICATION_LIVE will be used in process to tell if we are in a development or production environment.  It 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>");
}

Ответ 7

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

display_errors = On

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

Ответ 8

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

Ответ 9

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

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

Ответ 10

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

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

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

Ответ 11

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

Ответ 12

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

include /etc/nginx/fastcgi_params;

Пришел мне час, чтобы узнать это...

Ответ 13

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

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

Ответ 14

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

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

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

Ответ 15

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

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