views:

798

answers:

11

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.

A: 

Try catching exceptions and errors and logging them to a file.

rohit.arondekar
Doesn't PHP naturally do a stacktrace et al. when it encounters an uncaught exception?
Matthew Scharley
Maybe something is running in a infinite loop and timed out. Ideally you should get some kind of an error or warning. If you are looking for info on logging in PHP try http://www.devshed.com/c/a/PHP/Logging-With-PHP/
rohit.arondekar
I'm not talking about infinite loops. If I for example miss the closing bracket on a function call, all of a sudden, PHP just fails to run and returns a blank page.
Matthew Scharley
Could be something to do with PHP settings in the php.ini - try it on a local server or a different host maybe?Also take a look at this http://in.php.net/errorfunc
rohit.arondekar
+7  A: 

Errors and warnings usually appear in ....\logs\php_error.log or ....\logs\apache_erroe.log depending on your php.ini settings.

Also useful errors are often directed to the browser, but as they are not valid html they are not displayed.

So "tail -f" your log files and when you get a blank screen use IEs "view" -> "source" menu options to view the raw output.

James Anderson
Sadly, view page source displays nothing too.
Matthew Scharley
Parse errors should be visible in the Apache's error log, regardless of what setting you have anywhere else. If you don't have control over the server then getting the apache error log might be difficult, but I suggest you talk with your provider and there are ways to expose the error log to you. Other then that, I can only suggest what other have - vet your code for parsing errors in your local development server before you deploy to production. Also, a validating IDE such as Eclipse's PDT might be of great help.
Guss
+2  A: 

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.

I don't have access to php.ini. And when these errors pop up, it's a syntax error, so print_r doesn't help.
Matthew Scharley
If you don't have access to php.ini, you should not be developing on that server. Use shared hosting for production, your local machine for development.
carl
And when errors happen in production? We'd all like to believe that doesn't happen, but it does.
Matthew Scharley
If you have a parse error in production, something is wrong with your development model. :) If you have a different error, you don't want that error displayed to the user anyways + you should have a proper error handling mechanism.
carl
Mmm, a parse error in production would be interesting. And I don't disagree on any particular point, other than that I need to use the production server in this particular case because I have people testing it from outside my local LAN and I'd rather not expose my test server to the intertubes.
Matthew Scharley
I would suggest you download the apache XAMP or WAMPserver and set up a development environments on your PC. If your workstation environment is as constrained as your server environment you could use http://portableapps.com/apps/development/xampp which doesnt requires any admin rights or special priviledges to install and run.
James Anderson
I do have a local dev server. See my comment above, *I have people testing it from outside my local LAN and I'd rather not expose my test server to the intertubes.*
Matthew Scharley
A: 

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.

too much php
It is. `display_errors` is off in the serverwide config, but it displays lesser errors like parameter number mismatches, etc. I havn't used the `@` operator at all in this project, and generally tend to avoid it for just that reason.
Matthew Scharley
You should also check that display_errors is not being changed by a PHP script somewhere.
too much php
I've build this framework from the ground up, so no, it's not (unless something in the core changes it for some reason...)
Matthew Scharley
If you call an undefined function (to generate a fatal error), do you see that error message?
too much php
A: 

If every setting is proper did you use any set_error_handler() call?

The set_error_handler() function can make PHP to behave like this.

It can't handle fatal errors because they make the script stop immediatly.

Ifju
A: 

are you using output buffering? sometimes php will not flush the buffer in case of an error and you only get a white screen

knittl
I'm not personally using it, but the server might be setup to use it by default, I'm not sure.
Matthew Scharley
A: 

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.

Milan Babuškov
+1  A: 

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.

Denegen
+2  A: 

I'm always using this syntax at the very top of the php script.

ini_set('error_reporting', E_ALL);
ini_set('display_errors', 'On');  //On or Off
FDisk
I'm sorry, but -1 for not reading the other answers already posted. This is taken care of in the .htaccess as already mentioned several times.
Matthew Scharley
usual "free hosting" ignores the .htaccess
FDisk
Got me out of a bind. Thanks.
Hedley Lamarr
+3  A: 

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>");
}
Eli
Out of curiousity, where is `APPLICATION_LIVE` usually defined?
Matthew Scharley
@Matthew Scharley - Updated.
Eli
+1  A: 

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 )

Quamis