Friday, May 8, 2009

Error Reporting in PHP

Error Reporting

Types of Errors in PHP
Before we can get into remedying ugly error messages on your site, you need to understand the different types of errors. PHP4 can produce 11 different errors, as defined in Table 8-1 below (note that fatal errors stop the script from executing):

PHP Error Types

NAME VALUE DESCRIPTION
E_ERROR 1 Fatal error that occurs at script runtime.
E_WARNING 2 Nonfatal error that occurs at runtime (for example, if the script is unable to connect to MySQL).
E_PARSE 4 Error that occurs at compile time due to invalid syntax.
E_NOTICE 8 Nonfatal "notice." Not exactly an error, but a hint that you may be doing something you don't want to, such as dividing a number by zero.
E_CORE_ERROR 16 Fatal error that occurs when the PHP engine starts. You cannot run any PHP scripts if this error occurs.
E_CORE_WARNING 32 Nonfatal error that occurs when the PHP engine starts. You can still run PHP scripts, but you may have one or more problems depending on the error (for example, the GD library cannot be found).
E_COMPILE_ERROR 64 Fatal error that occurs when the script is compiled.
E_COMPILE_WARNING 128 Nonfatal error that occurs when the script is compiled.
E_USER_ERROR 256 User-generated fatal error. Same as E_ERROR, but never thrown by PHP. You can throw this error with the trigger_error() function. If you are using PHP's default error handler, then using this error causes script execution to stop.
E_USER_WARNING 512 User-generated nonfatal error. Same as E_WARNING, but never thrown by PHP. You can throw this error with the trigger_error() function.
E_USER_NOTICE 1024 User-generated notice. Same as E_NOTICE, but never thrown by PHP. You can throw this error with the trigger_error() function.
E_ALL 2047 Not really a type of error. Instead, it is all the errors rolled into one. This makes it easy to say that you want to report all of the errors when using the error_reporting() function.


Of all of these errors, the ones you should mainly concern yourself when it comes to reporting and logging are the following:

E_WARNING

E_NOTICE

E_USER_ERROR

E_USER_WARNING

E_USER_NOTICE

Other errors that occur usually result in the script not executing. Your reporting and logging function won't even be run, since there is no script execution.

Error Reporting Settings in php.ini
Side Note
This information applies to PHP Version 4 and later. These settings do not work with PHP Version 3.


The reason you see those "ugly" errors when you are coding is that PHP by default is set to show all errors (E_ALL), with the exception of PHP-generated notices (E_NOTICE). Open your php.ini file and scroll down to the section entitled "Error handling and logging." At the end of all those comments, you should see a line like the following:

error_reporting = E_ALL & ~E_NOTICE

This is the default error reporting setting. It's written using bitwise operators and is translated simply to "For Error Reporting Use Everything And Not E_NOTICE." You could also write it as follows (note that we leave out E_NOTICE):

[View full width]
error_reporting = E_ERROR | E_WARNING | E_PARSE | E_CORE_ERROR | E_CORE_WARNING |
E_COMPILE_ERROR | E_COMPILE_WARNING | E_USER_ERROR | E_USER_WARNING | E_USER_NOTICE

However, since you are a PHP developer, you really should set this line to read as follows when you are developing an application:

error_reporting = E_ALL

You want to see all the errors that your script is producing. You'd be surprised at how many uninitialized variables you might be using.

error_reporting()
The error_reporting() function allows you to override the default error reporting setting used in php.ini:

error_reporting(settings);

The error_reporting function takes one argument, which can either be a string that lists the names of the error reporting settings that you want to use (separated by bitwise operators), or an integer that is the sum of the values that you want to use. For example:

error_reporting(10);

is equivalent to:

error_reporting("E_WARNING | E_NOTICE");

The first version is easier to type, but the second version is more verbose. Additionally, you can subtract values from the E_ALL value (2047) to use "all but" reporting. The example below allows you to display all errors (E_ALL) except for E_NOTICE (2047 - 8):

error_reporting(2039);

If you do not want to report any errors, then you could simply use:

error_reporting(0);

This stops PHP from displaying any error messages on the screen that are caused by E_WARNING, E_NOTICE or any of the user-thrown warnings. Remember, any of the other warnings are thrown automatically by PHP because there is something either really wrong with the script (parse errors) or really wrong with the server itself.

You still may run into a problem if there is an error that causes the script to fail to compile (such as with parse errors). In that case, no portions of your script are even executed, and the error_reporting() variable is not run. When this happens, PHP uses its php.ini setting for error reporting.

php.ini Setting: display_errors
Additionally, there is another setting that stops error messages from being displayed on the user's browser. This setting, display_errors, can be found in php.ini. In the event that you want to be sure that errors are never displayed on the screen, you can change this setting to "0" in your php.ini file. You should leave this setting to "1" or "On" while you are developing your application.

You can also change the display_errors setting on a per file basis using the ini_set() function. The ini_set() function allows you to change php.ini file settings for the current script. For example, if you had turned off display_errors in your php.ini file, then you could turn it on to debug your script by using the following code, which is the php.ini equivalent of display_errors = On:

ini_set("display_errors",1);

Remember, if your script encounters an error that does not allow it to execute, then PHP uses the settings it finds in php.ini, regardless of what you have specified in your script.

No comments: