Any developer needs to handle php errors regardless of the language they use. Lets talk about the error handling capabilities of php. One of the key features of php scripting language is it’s detail error-handling functionality. Developers could control many aspects of how errors are occurred and handled. In this article we will find out what are the key concepts of errors and error handling in php coding.

What type of php errors can occur?

The developers may encounter many number of different error types that may be occurred in php code. Some of these php errors can be recovered and handled, while others cannot (that is, some errors will cause the current script execution to directly terminate. we call these errors show stoppers).

Following list of errors are taken from the PHP manual.

  • 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 halted
  • E_WARNING: Run-time warnings (non-fatal errors). Execution of the script is not halted
  • E_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 an E_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 an E_WARNING, except it is generated by the core of PHP.
  • E_COMPILE_ERROR: Fatal compile-time errors. This is like an E_ERROR, except it is generated by the Zend Scripting Engine
  • E_COMPILE_WARNING: Compile-time warnings (non-fatal errors). This is like an E_WARNING, except it is generated by the Zend Scripting Engine
  • E_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 an E_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 code
  • E_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 an E_ERROR
  • E_DEPRECATED: Run-time notices. Enable this to receive warnings about code that will not work in future versions
  • E_USER_DEPRECATED: User-generated warning message. This is like an E_DEPRECATED, except it is generated in PHP code by using the PHP function trigger_error()

Assume you get one of the above php errors occurs, whether or not it is reported is determined by the error_reporting setting.

  • You can set this option either in php.ini
  • You can set it in your web server such as in httpd.conf or a .htaccess file.
  • You can set it at runtime (that is, from within your PHP script)

By setting it in your php.ini can combine the php error constants into a bitwise mask. The following listing shows couple of examples that can be used in php.ini.

code snippet
error_reporting = E_ALL & ~E_NOTICE ; hide all errors
error_reporting = E_WARNING | E_NOTICE ; warnings or notices

If you set the php error level in httpd.conf or in .htaccess, these constant names do not exist. You must use their corresponding integer values instead.

The following code snippet shows a sample .htaccess file:

Code snippet
# sets E_ALL & E_NOTICE - E_ALL is 30719 in PHP 5.3, 6143 in PHP 5.2
php_value error_reporting 30711

# sets E_WARNING | E_NOTICE (2 | 8)
php_value error_reporting 10

You can do the same thing at run-time, by using either ini_set() or error_reporting(). Below code snippet show how you can do it at run-time

Code snippet
<?php
    ini_set('error_reporting', E_ALL & ~E_NOTICE);
    error_reporting(E_WARNING | E_NOTICE);
?>

Some other useful trick is to temporarily set a new error level, then return back to the old one once you’re finish executing. It can be useful if you want to report on deprecated features normally, but a third-party library you’re using would cause a whole heap of warnings otherwise.

You get the current setting  by calling error_reporting(). You can store this value temporarily.

Code Snippet
<?php
    // recover 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);
?>

What Ways php Errors Reported?

There are typically two ways that php errors are reported:

  1. Into a log file
  2. On to the screen (or browser client)

In common practice displaying errors to the end-user is only used in development or for debugging. Production or the live web sites should write errors to log files and display meaningful messages to the end-user.

You can use the display_errors configuration directive. It is a boolean value that controls whether or not php errors are displayed.

You cab in cooperate above setting in the httpd.conf or .htaccess files and you can disable php error display. Following code snippet shows how to do it;

Code snippet
php_value display_errors Off

In order to log errors into a filesystem, enable the log_errors setting. By default this will write php errors to the server’s error log.

You can use a different log file by setting the error_log directive. The following listing shows what you would include in your configuration file to write php error messages to a custom path.

code snippet
php_value log_errors On
php_value error_log /path/to/site/logs/php-errors.log

Creating Your Own Errors

It is possible to create PHP custom errors whenever you want by using the trigger_error() function. The first argument is  the detail php error message (max allowed 1024 characters) and the second argument is the type of error (if unspecified the default is E_USER_NOTICE).

A practical scenario where you would create your own php errors is when writing a custom PHP library that others can use. You can create 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.

Following listing shows how to manually create an error with in your code.

code snippet
<?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

One good feature of PHP, it allows you to prefix expressions with the @ sign, which sets php error reporting to 0 just for that expression. While this should be used in a managed manner, it is useful in some situations.

For instance, when you use fopen() to open a file handle, if opening fails an error E_WARNING is triggered. Your code should always check for the error handler.

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.

Code snippet
<?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 php Error Handler

As shown above, PHP will either write php errors to screen or to a log file, or both. You can instead use a custom php error handler, which bypasses both of these methods completely.

Important: In fact, you must return true from the callback, otherwise the standard PHP error handler will be called afterwards.

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:

  1. $errno (integer) – The level of the error raised (e.g. E_WARNING)
  2. $errstr (string) – The error message describing the error
  3. $errfile (string, optional) – The filename the error was raised in
  4. $errline (integer, optional) – The line number in the file the error was raised
  5. $errcontext (array, optional) – An array that points to the active symbol table

The following code shows a basic error handler. Since all error messages are passed to the handler despite the error reporting setting, it can be honored as shown in the first line of the errorHandler function.

code snippet

<?php
    function errorHandler($errno, $errstr, $errfile, $errline, $errcontext)
    {
        // use bitwise operators to check error reporting setting
        if (error_reporting() & $errno == 0) {
            // no reporting on this message
            return;
        }

        // check type of error then 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);
?>

If you want to your script to finish execution when certain error occurs, you must manually exit (by calling exit() or die()) from your error handler.

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.”