PHP's white screen of death

2018-12-30 23:02发布

Now that I'm starting to get back into PHP, I'm starting to remember why I gave it up in the first place. The most annoying thing on my plate at the moment is what I've come to term "PHP's white screen of death". When PHP gets a fatal error due to syntax or whatever, it seems like it will always die without actually sending anything to the browser. I've added the following to my .htaccess, and it seems to work most of the time, but it doesn't work in these cases.

php_value display_errors 1
php_value display_startup_errors 1
php_value error_reporting 2147483647 # E_ALL

Am I missing something? At the moment I feel like I need to hit refresh every few lines of code I write, lest I make a mistake and have to search through many pages trying to track down that one little mistake I made...

EDIT: For example, given the two lines of code below:

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

The first will exhibit the white screen of death (ie, nothing at all printed to the browser), while the second will execute happily.

15条回答
流年柔荑漫光年
2楼-- · 2018-12-30 23:58

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.

查看更多
姐姐魅力值爆表
3楼-- · 2018-12-31 00:00

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.

查看更多
只若初见
4楼-- · 2018-12-31 00:02

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.

查看更多
登录 后发表回答