
Blank Screen *
This may seem obvious for experienced developers, but I’ll say it anyway: turn on your errors during development. 99% of the time, the notorious “blank screen” means that you have an error, and it’s not being displayed. (In the other 1% of the cases, you are not actually outputting anything to screen and I have no remorse for you.)
There are several ways to set error reporting in PHP, but before I get to that…
DISCLAIMER: While you should display errors on your development sites, you should NEVER display errors on production server, but log them instead. It’s a huge security issue, since sensitive data IS displayed in the errors, which makes your site vulnerable to attacks.
OK, not that that’s out of the way, here’s how you can set PHP error reporting:
1. PHP Configuration file: php.ini
Just modify the lines in your php.ini like so:
error_reporting = E_ALL & ~E_NOTICE
display_errors = On
The code above will show all errors, except for notices about potential issues and coding standards warnings, on screen. Those funny squiggly things are Bitwise Operators, and you can read the error reporting level above as “E_ALL and not E_NOTICE”.
This is one of the most commonly used error reporting levels, but if you really want to follow the best practices, I suggest setting error_reporting level to E_ALL | E_STRICT, which will display all errors, plus make your code “future-proof” by pointing out soon-to-be-deprecated items.
2. Apache: .htaccess & httpd.conf
If you don’t have access to your php.ini file, you can create an .htaccess file and place it in the root of your document, or edit the one already there. Just adding these lines to .htaccess will have the same effect as the php.ini method above:
php_value error_reporting 6135
php_flag display_errors true
If you are wondering where the 6135 came from, it’s the integer representation of E_ALL & ~E_NOTICE. Each of the predefined PHP error level constants has an integer value. And since .htaccess is not processed by PHP, we don’t have access to constants yet, so we must use integers.
Basically, 6135 is 6143 (E_ALL) – 8 (E_NOTICE). Check out the rest of Predefined Constants and their integer values. You can also quickly figure out the number you need by echoing the desired expression in your PHP script, like so:
echo E_ALL & ~E_NOTICE;
One gotcha to this is that integer value of E_ALL has been changing from version to version (with new error levels being included into E_ALL). Incidentally the line of code above will return 30711 in PHP 5.3, as opposed to 6135 in PHP 5.2. So if you want to display all errors and notices possible, just use
php_value error_reporting -1
You also have an option to set these values in httpd.conf, however I am yet to encounter a situation where it would be the best place to set error reporting.
3. PHP file
I personally prefer this method to the other two. There are several advantages to it:
- Sometimes it can be the only way to set error reporting. You don’t have access to tweaking php.ini or restarting the server, or .htaccess may be disabled on the host.
- If you are using some sort of framework with a common front controller or bootstrap, it’s the best place to put error reporting. It lets you turn errors on and off depending on the environment. As a matter of fact, most MVC frameworks will have this built in already.
- You can place the code anywhere in your PHP document, in case you need to quickly debug a single file or area.
As you can see, you will use the same constants as in php.ini file.
if (/... some kind of in development flag .../) {
ini_set('display_errors', TRUE);
}
else {
ini_set('display_errors', FALSE);
}
error_reporting(E_ALL & ~E_NOTICE);
The “in development” flag may be something you set in a configuration file, based on the environment.
If you must turn the errors on on production server temporarily, there are a couple ways you can do it without displaying them to the whole world. These are to be used only when stuff hits the fan.
- You can limit them to only your own IP address, using the little trick below. Replace
[ my IP ] with your real IP address, which you can get from a site like http://www.whatismyip.com/. Just keep in mind that both of these values can be spoofed.
if ($_SERVER['REMOTE_ADDR'] == '[ my IP ]' || $_SERVER['HTTP_X_FORWARDED_FOR'] == '[ my IP ]') {
// Turn on error reporting here.
}
- You could also create a page that sets a specific session value, and only display errors based on that session value. In other words, get creative, but don’t get carried away.
There’s a gotcha here as well. This will NOT report any syntax errors, like a missing semicolon or comma. That’s because syntax errors happen during the compilation of your file, so it “breaks” before it’s told to report errors, and you will get a blank screen.
The best way around that is to have a single error-free bootstrap file, which will turn on error display and then include other files (this is the case in most MVC frameworks). Sometimes that’s not an option, and you have a single file with a syntax error that you are unable to find. In that case, if you have access to command-line, just run your file from there:
$ php myfile.php
Even though the logic in the file won’t work, the compiler will report syntax errors. Another option is to copy the file to a server that has error reporting enabled and find your syntax errors that way.
So, which one to use!?
So many options… Like a lot of things in programming, it’s largely a matter of taste. But here’s my preference.
- If you have a dedicated development server, you should use php.ini. Set it and forget it, so to speak.
- If your application has a common file, like a front controller or bootstrap, use the PHP method. That way you can easily control error display on the application level, based on environment and other factors.
- .htaccess is best if you don’t have access to php.ini, and you don’t have a front-controller application.
* Photo by toasty
** This post is part of Debugging PHP, Guerilla Style series.