IT

PHP의 죽음의 하얀 화면

lottoking 2020. 7. 2. 07:31
반응형

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

첫 번째는 하얀 화면의 죽음을 나타내며 (즉, 브라우저에 아무것도 인쇄되지 않음) 두 번째는 행복하게 실행됩니다.


오류 및 경고는 보통의 표시 ....\logs\php_error.log또는 ....\logs\apache_error.logphp.ini 파일 설정에 따라.

또한 유용한 오류는 종종 브라우저로 전송되지만 유효한 HTML이 아니기 때문에 표시되지 않습니다.

따라서 "tail -f"로그 파일과 빈 화면이 표시되면 IE"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

?>

이 코드로 빈 페이지를 생성하는 유일한 방법은 종료 처리기에 오류가있는 경우입니다. 나는 그것을 테스트하지 않고 내 자신의 cms에서 이것을 복사하여 붙여 넣었지만 작동한다고 확신합니다.


나는 항상이 스크립트를 PHP 스크립트 맨 위에 사용하고 있습니다.

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

It is possible to register an hook to make the last error or warning visible.

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

register_shutdown_function('shutdown');

adding this code to the beginning of you index.php will help you debug the problems.


This is a problem of loaded vs. runtime configuration

It's important to recognize that a syntax error or parse error happens during the compile or parsing step, which means that PHP will bail before it's even had a chance to execute any of your code. So if you are modifying PHP's display_errors configuration during runtime, (this includes anything from using ini_set in your code to using .htaccess, which is a runtime configuration file) then only the default loaded configuration settings are in play.

How to always avoid WSOD in development

To avoid a WSOD you want to make sure that your loaded configuration file has display_errors on and error_reporting set to -1 (this is the equivalent E_ALL because it ensures all bits are turned on regardless of which version of PHP you're running). Don't hardcode the constant value of E_ALL, because that value is subject to change between different versions of PHP.

Loaded configuration is either your loaded php.ini file or your apache.conf or httpd.conf or virtualhost file. Those files are only read once during the startup stage (when you first start apache httpd or php-fpm, for example) and only overridden by runtime configuration changes. Making sure that display_errors = 1 and error_reporting = -1 in your loaded configuration file ensures that you will never see a WSOD regardless of syntax or parse error that occur before a runtime change like ini_set('display_errors', 1); or error_reporting(E_ALL); can take place.

How to find your (php.ini) loaded configuration files

To locate your loaded configuration file(s) just create a new PHP file with only the following code...

<?php
phpinfo();

Then point your browser there and look at Loaded Configuration File and Additional .ini files parsed, which are usually at the top of your phpinfo() and will include the absolute path to all your loaded configuration files.

If you see (none) instead of the file, that means you don't have a php.ini in Configuration File (php.ini) Path. So you can download the stock php.ini bundled with PHP from here and copy that to your configuration file path as php.ini then make sure your php user has sufficient permissions to read from that file. You'll need to restart httpd or php-fpm to load it in. Remember, this is the development php.ini file that comes bundled with the PHP source. So please don't use it in production!


Just don't do this in production

This really is the best way to avoid a WSOD in development. Anyone suggesting that you put ini_set('display_errors', 1); or error_reporting(E_ALL); at the top of your PHP script or using .htaccess like you did here, is not going to help you avoid a WSOD when a syntax or parse error occurs (like in your case here) if your loaded configuration file has display_errors turned off.

Many people (and stock installations of PHP) will use a production-ini file that has display_errors turned off by default, which typically results in this same frustration you've experienced here. Because PHP already has it turned off when it starts up, then encounters a syntax or parse error, and bails with nothing to output. You expect that your ini_set('display_errors',1); at the top of your PHP script should have avoided that, but it won't matter if PHP can't parse your code because it will never have reached the runtime.


Dunno if it will help, but here is a piece of my standard config file for php projects. I tend not to depend too much on the apache configs even on my own server.

I never have the disappearing error problem, so perhaps something here will give you an idea.

Edited to show 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>");
}

open your php.ini, make sure it's set to:

display_errors = On

restart your server.


For those who use nginx and have a white screen even for file with <?php echo 123;. In my case I didn't have this required option for PHP in nginx config file:

fastcgi_param scriptFILENAME $document_root$fastcgi_scriptname;

This option wasn't in fastcgi_params file, so PHP didn't work and there wasn't any errors in logs.


Try setting your error reporting level in your actual php files. Or, as others have suggested, check your server settings--it could be something in php.ini, or some restriction as regards your host. Don't just rely on .htaccess. Also, when troubleshooting, print_r any variables you might think fishy.


Are you sure PHP is actually picking up the 'display_errors' setting from .htaccess? Check the output of the phpinfo() function to make sure.

Also, you should check to make sure that you haven't used '@', it could be silencing your errors if you have used '@include ...' or '@some_function(...)', somewhere up the stack trace.


Some applications do handle these instructions themselves, by calling something like this:

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

And thus overriding your .htaccess settings.


using @inexistent_function_call(); in your code will cause the intepreter to quietly die and abort the script parsing. You should check for invalid functions and try not to use the error-supressing operator(the @ char )


I have also seen such errors when the fastcgi_params or fastcgi.conf config file is not properly included in the server configuration. So the fix for me was a silly:

include /etc/nginx/fastcgi_params;

Took me an hour to find that out...


You can also run the file in the Terminal (command line) like so: php -f filename.php.

This runs your code and gives you the same output in case of any errors that you'd see in the error.log. It mentions the error and the line number.


If the error is in PHP code, you can use error_reporting() function within your code to set to the report all.

However, this does not handle the situation when PHP crashes. Information about that is only available in server logs. Maybe you don't have access to those, but many hosting providers I've worked with have some way to let you access it. For example, the approach I like best is that it creates the error_log file in the current directory where .php resides. Try searching there or contact your hosting provider about this.

참고URL : https://stackoverflow.com/questions/1475297/phps-white-screen-of-death

반응형