Вопрос

Теперь, когда я начинаю возвращаться к 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);

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

Это было полезно?

Решение

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

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

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

Другие советы

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

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

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

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

Важно понимать, что синтаксическая ошибка или ошибка синтаксического анализа возникает во время скомпилировать или синтаксический анализ шаг, который означает, что 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 или файл virtualhost.Эти файлы считываются только один раз на этапе запуска (например, при первом запуске apache httpd или php-fpm) и переопределяются только при изменениях конфигурации среды выполнения.Убедившись , что display_errors = 1 и error_reporting = -1 в вашем загруженном файле конфигурации гарантирует, что вы никогда не увидите ВСОД независимо от синтаксической ошибки или ошибки синтаксического анализа, которые возникают перед изменением среды выполнения, например 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 .Кроме того, при устранении неполадок выводите_r любых переменных, которые могут показаться вам подозрительными.

Вы уверены, что PHP действительно улавливает 'display_errors' настройка из .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.В нем упоминается ошибка и номер строки.

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top