PHP A to ZCE: Error Handling
This article is part of the series “PHP A to Zend Certified Engineer”.
In PHP A to ZCE, I will take you through 26
different yet equally important topics that will help you become a Zend
Certified Engineer. Even if you're not interested in sitting the ZCE-PHP
exam, these topics will elevate your understanding of PHP to a whole
new level and allow you to become the guru in your company.
Read more about PHP A to Zend Certified Engineer...
One of the features of PHP is its comprehensive error-handling
functionality. You can control many aspects of how errors are triggered
and handled. In this article I will cover the key aspects of errors and
error handling in PHP.
Types of Errors
There are a number of different error types that may be triggered in PHP. Some of these can be recovered from, while others cannot (that is, some errors will cause the current script execution to immediately halt).The following list is from the PHP manual entry on Error Predefined Constants.
E_ERROR
: Fatal run-time errors. These indicate errors that can not be recovered from, such as a memory allocation problem. Execution of the script is haltedE_WARNING
: Run-time warnings (non-fatal errors). Execution of the script is not haltedE_PARSE
: Compile-time parse errors. Parse errors should only be generated by the parser.E_NOTICE
: Run-time notices. Indicate that the script encountered something that could indicate an error, but could also happen in the normal course of running a script.E_CORE_ERROR
: Fatal errors that occur during PHP's initial startup. This is like anE_ERROR
, except it is generated by the core of PHP.E_CORE_WARNING
: Warnings (non-fatal errors) that occur during PHP's initial startup. This is like anE_WARNING
, except it is generated by the core of PHP.E_COMPILE_ERROR
: Fatal compile-time errors. This is like anE_ERROR
, except it is generated by the Zend Scripting EngineE_COMPILE_WARNING
: Compile-time warnings (non-fatal errors). This is like anE_WARNING
, except it is generated by the Zend Scripting EngineE_USER_ERROR
: User-generated error message. This is like an E_ERROR, except it is generated in PHP code by using the PHP function trigger_error()E_USER_WARNING
: User-generated warning message. This is like anE_WARNING
, except it is generated in PHP code by using the PHP function trigger_error()E_USER_NOTICE
: User-generated notice message. This is like an E_NOTICE, except it is generated in PHP code by using the PHP function trigger_error()E_STRICT
: Enable to have PHP suggest changes to your code which will ensure the best interoperability and forward compatibility of your codeE_RECOVERABLE_ERROR
: Catchable fatal error. It indicates that a probably dangerous error occured, but did not leave the Engine in an unstable state. If the error is not caught by a user defined handle (see also set_error_handler()), the application aborts as it was anE_ERROR
E_DEPRECATED
: Run-time notices. Enable this to receive warnings about code that will not work in future versionsE_USER_DEPRECATED
: User-generated warning message. This is like anE_DEPRECATED
, except it is generated in PHP code by using the PHP function trigger_error()
E_ALL
. This includes all errors and warnings, except for E_STRICT
.
Which Errors Are Reported?
When one of the above errors occurs, whether or not it is reported is determined by theerror_reporting
setting.
- You can set this either in
php.ini
- You can set it in your web server configuration (such as in
httpd.conf
or a.htaccess
file) - You can set it at runtime (that is, from within your PHP script)
php.ini
you can combine the above error constants into a bitwise mask. The following listing shows two examples that can be used in php.ini
.
Listing 1 listing-1.txt
error_reporting = E_ALL & ~E_NOTICE ; all errors and not notices error_reporting = E_WARNING | E_NOTICE ; warnings or notices
httpd.conf
or in .htaccess
, these constant names do not exist. You must use their corresponding integer values instead.
The following shows a sample
.htaccess
file:
Listing 2 listing-2.txt
# this sets E_ALL & ~E_NOTICE - E_ALL is 30719 in PHP 5.3, 6143 in PHP 5.2 php_value error_reporting 30711 # this sets E_WARNING | E_NOTICE (2 | 8) php_value error_reporting 10
Listing 3 listing-3.php
ini_set('error_reporting', E_ALL & ~E_NOTICE); error_reporting(E_WARNING | E_NOTICE);
When you call error_reporting(), the current setting is returned. You can store this value temporarily.
Listing 4 listing-4.php
// retrieve original reporting level then disable error reporting $oldLevel = error_reporting(0); // do something that might cause notices or warnings // all done: restore old level error_reporting($oldLevel);
How Are Errors Reported?
There are essentially two ways that are errors are reported:- To a log file
- To the screen (or end-user's browser)
The
display_errors
configuration directive is a boolean value that controls whether or not errors are displayed.
In a
httpd.conf
or .htaccess
file you can disable this with the following:
Listing 5 listing-5.txt
php_value display_errors Off
log_errors
setting. By default this will write errors to the server's error log (in Apache, this would be the file specified with the ErrorLog
directive).
You can use a different log file by setting the
error_log
directive. The following listing demonstrates what you would include in
your Apache configuration to write error messages to a custom path.
Listing 6 listing-6.txt
php_value log_errors On php_value error_log /path/to/site/logs/php-errors.log
Triggering Your Own Errors
It is possible to trigger PHP errors whenever you want to using the trigger_error() function. The first argument is a descriptive error message (limited to 1024 characters) and the second argument is the type of error (if unspecified the default isE_USER_NOTICE
).
The typical scenario where you would trigger your own errors is when writing a custom PHP library that others can use. You can trigger errors in situations where the library isn't being correctly used (or where some other runtime issue occurred)
Note: You could use exceptions in PHP instead, or you could use a combination of custom error triggering and exceptions.
The following listing demonstrates how you might manually trigger an error in your code.
Listing 7 listing-7.php
function myFunc($anInteger) { if (!is_int($anInteger)) { trigger_error( 'First argument to myFunc() must be an integer', E_USER_NOTICE ); } // do something } myFunc('A string');
The @ Error Control Operator
PHP allows you to prefix expressions with the@
, which sets error reporting to 0
just for that expression. While this should be used sparingly (your
code should have appropriate error checks), it is useful in some
situations.
For instance, when you use fopen() to open a file handle, if opening the file fails an error of level
E_WARNING
is triggered. Your code should always check whether or not the call
worked anyway (it may be designed that it can fail in some instances).
In this instance, even if you expected the call to fail, you would have to suppress all warnings (including legitimate ones you want to know about) just to avoid the warning on fopen(). This is where
@
can be useful. The following listing demonstrates this.
Listing 8 listing-8.php
error_reporting(E_ALL); // suppress the warning if this fails since we check for failure $fp = @fopen('/path/to/some/file', 'r'); if (!$fp) { // unable to open file }
Using a Custom Error Handler
As previously mentioned, PHP will either write errors to output or a log file, or both. You can instead use a custom error handler, which bypasses both of these mechanisms completely.
Important: In fact, you must return
This is achieved using the set_error_handler() function. This function accepts a PHP callback as its first argument. This callback accepts up to 5 arguments:
true
from the callback, otherwise the standard PHP error handler will be called afterwards.
$errno
(integer) - The level of the error raised (e.g.E_WARNING
)$errstr
(string) - The error message describing the error$errfile
(string, optional) - The filename the error was raised in$errline
(integer, optional) - The line number in the file the error was raised$errcontext
(array, optional) - An array that points to the active symbol table
errorHandler
function.
Listing 9 listing-9.php
function errorHandler($errno, $errstr, $errfile, $errline, $errcontext) { // use bitwise operators to check the error reporting setting if (error_reporting() & $errno == 0) { // we're not to report on this message return; } // check the type of error so it can be handled accordingly switch ($errno) { case E_USER_ERROR: echo sprintf( 'User Error: %s (file %s, line %d)', $errstr, $errfile, $errline ); break; case E_USER_WARNING: // output a message break; // handle other error numbers accordingly } // return true so standard error handler is bypassed return true; } // tell PHP to use the error handler set_error_handler('errorHandler'); // trigger a fake error just to demonstrate the callback trigger_error('Fake error', E_USER_ERROR);
One final note: Not all types of errors can be dealt with using a custom error handler. From the PHP manual:
“The following error types cannot be handled with a user defined function:
E_ERROR
, E_PARSE
, E_CORE_ERROR
, E_CORE_WARNING
, E_COMPILE_ERROR
, E_COMPILE_WARNING
, and most of E_STRICT
raised in the file where set_error_handler() is called.”
Other Options
- Download a PDF version of this article
- Put your PHP knowledge to the test with our online and iPad/iPhone quizzes
- View or post comments for this article
- Browse similar articles by tag: PHP, ZCE
- Read related articles:
No comments:
Post a Comment