Теперь, когда я начинаю возвращаться к 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);
На первом отобразится белый экран смерти (т. Е. Ничего не будет напечатано в браузере), а второй – с радостью.
Ошибки и предупреждения обычно появляются в ....\logs\php_error.log
....\logs\apache_error.log
....\logs\php_error.log
или ....\logs\apache_error.log
зависимости от ваших настроек php.ini.
Также полезные ошибки часто направляются в браузер, но поскольку они недействительны html, они не отображаются.
Итак, "tail -f
» ваши файлы журналов, и когда вы получаете пустой экран, используйте параметры меню «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 ?>
значение<?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
Важно признать, что во время этапа компиляции или синтаксического анализа происходит синтаксическая ошибка или синтаксическая ошибка, что означает, что PHP закроется, прежде чем даже сможет выполнить какой-либо из ваших кодов. Поэтому, если вы display_errors
конфигурацию display_errors
PHP во время выполнения (это включает в себя что угодно: от использования ini_set
в вашем коде до использования .htaccess, который является файлом конфигурации во время выполнения), тогда загружаются только загруженные настройки конфигурации по умолчанию .
Чтобы избежать 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 только с помощью следующего кода …
<?php phpinfo();
Затем укажите свой браузер и посмотрите на загруженный файл конфигурации и дополнительные файлы .ini , которые обычно находятся в верхней части вашего phpinfo()
и будут содержать абсолютный путь ко всем загруженным конфигурационным файлам.
Если вы видите (none)
вместо файла, это означает, что у вас нет файла php.ini в файле Configuration File (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 не разобрать ваш код, потому что он никогда не достигнет времени исполнения.
Dunno, если это поможет, но вот часть моего стандартного файла конфигурации для проектов 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>"); }
Можно зарегистрировать крючок, чтобы сделать последнюю ошибку или предупреждение видимым.
function shutdown(){ var_dump(error_get_last()); } register_shutdown_function('shutdown');
добавив этот код в начало вам, index.php поможет вам отладить проблемы.
откройте свой php.ini, убедитесь, что он установлен в:
display_errors = On
перезагрузите сервер.
Попробуйте настроить уровень сообщений об ошибках в ваших действительных файлах 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.
используя @inexistent_function_call();
в вашем коде заставит intepreter спокойно умереть и прекратить разбор сценариев. Вы должны проверить недопустимые функции и попытаться не использовать оператор подавления ошибок (@ char)
Я также видел такие ошибки, когда fastcgi_params
или fastcgi.conf
конфигурации fastcgi.conf
неправильно включены в конфигурацию сервера. Так что исправление для меня было глупо:
include /etc/nginx/fastcgi_params;
Принял мне час, чтобы узнать это …
Вы также можете запустить файл в Terminal (командной строке) следующим образом: 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 () в вашем коде, чтобы установить для всего отчета.
Однако это не справляется с ситуацией, когда сбой PHP. Информация об этом доступна только в журналах сервера. Возможно, у вас нет доступа к ним, но многие хостинг-провайдеры, с которыми я работал, могут каким-то образом позволить вам получить к нему доступ. Например, подход, который мне больше всего нравится, заключается в том, что он создает файл error_log в текущем каталоге, где находится .php. Попробуйте найти там или обратитесь к вашему провайдеру хостинга.