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



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



php_value display_errors 1
php_value display_startup_errors 1
php_value error_reporting 2147483647 # E_ALL


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



EDIT: например, даны две строки кода ниже:



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


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

959   15  

15 ответов:

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

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

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

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

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

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

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

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

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

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

загруженная конфигурация-это либо ваш загруженный или 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 in конфигурационный файл (php.ini) Path. Так что вы можете скачать 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 не может разобрать ваш код, потому что он никогда не достигнет времени выполнения.

Не знаю, поможет ли это, но вот часть моего стандартного конфигурационного файла для 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

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

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

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

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

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

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

и, таким образом, переопределение .htaccess параметры.

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

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

include /etc/nginx/fastcgi_params;

мне час чтобы выяснить это...

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

это запускает ваш код и дает вам тот же вывод в случае каких-либо ошибок, которые вы видели в error.log. В нем упоминается ошибка и номер строки.

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

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

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

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

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

Comments

    Ничего не найдено.