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. Попробуйте найти там или обратитесь к вашему провайдеру хостинга.