Updated Nov 7, 2016 by Greg

PHPDevShell offers three errors-related mechanisms which can sometimes confuse the new user because they seems similar at first sight:

  • Errors occurs when an unexpected problem cannot be solved by the program
  • Exceptions, is a standard mechanism allowing the program to handle special cases
  • Debug provides the user tools to interact with the program in order to fix bugs
    These three mechanisms interact with each other so we will study all three here.

These are three separate, however related, concepts.

Errors

Errors occur when something goes wrong at the language level: a typo, an impossible action (division by zero), a type error… They are generated by the PHP engine. Depending on the configuration, they can be left alone (not wise, it will break the script), or handled by PHPDevShell and turned into an special exception called ErrorException.

You can divide errors into three generic categories: notices (a situation which is probably harmless), warning (a situation which is likely problematic) and critical (abandon all hopes). The usual policy is to display notices and keep the cycle running, and handle everything else as a dead end. You can configuration everything to suit your needs (see below).

Exceptions

Present in most modern languages, the goal of the exception mechanism is to deal with “special cases” out of the main stream of code. The advantages of using it are:

  • protection: any error occurring anywhere in the function or the functions it calls can be caught
  • code readability: the error handling code is distinct and doesn’t mess with the main code
  • error versatility: many types of errors can be handled, even if they’re not known from the developer
  • responsibility: the function can handle some errors and leave the other to someone else

You can read about PHP exception in the online manual. PHPDevShell allows and uses Exceptions everywhere in the code. A top-level exception handler is provided in case a thrown exception is not caught anywhere else.

Example (from PHPDevShell code):

try {
	$this->db->get_essential_settings();
} catch (Exception $e) {
	session_destroy();
	header('Location: install.php');
}

That means: we try to fetch the essential settings from the database. In case we fail, we assume we need install is needed.

Debug

The debugging modules provided by PHPDevShell are basically extended error_log() functions. They are not designed to substitute for PHP debuggers such as Zend Debug or XDebug. They use the conduits configured by the ExceptionHandler to send data to the developer.

The ExceptionHandler

The ExceptionHandler’s job is to react to such situations by reporting them according to the site’s configuration. The reports can be sent through various conduits and should contain as much information as possible to help the site’s owner/developer to give the appropriate response.

Currently the following conduits are available:

  • on screen (on production site, it’s better to let the user know an error occurred with no more information to avoid security leaks)
  • through FireBug/FirePHP (only for development)
  • by mail (to inform the site owner if he’s not monitoring the site in real time)
  • on syslog

Each can be activated and configured separately.

Depending on the conduit, the report contains information such as the location of the error, the timestamp when it occured, the backtrace of the function which triggered the error, etc.

Overview

You can see how these interact in this picture:

The relationships and interactions of Errors, Exceptions and Debug in PHPDevShell

Enabling and disabling

  • The exception mechanism is built in PHP so it cannot be disabled. If don’t want to use it, just don’t.
  • The error handler is part of PHPDevShell and cannot be disabled; however you can enable/disable each conduit, so if you disabled all conduits, you won’t receive any message.
  • The debug can be disabled (useful for production sites) based on the concept of “domains” (refer to the documentation for debug).

Remember: on a production site, debug MUST be disabled but errors MUST be handled (nicely).

Configuration

The configuration files allow you to:

  • tell how you want error types to be handled (break on notices or not, on warnings, etc)
  • filter what kind of error you want to to be handled (it’s usually a good thing to catch all errors)
  • set which conduits should sent the information where

Note: if a warning or a notice occurs when set to non-fatal, they won’t be converted to exception and therefore won’t be catchable. They will, however, be displayed, unless configured to be ignored. Refer to this table:

fatal = false fatal = true
ignore = true not displayed, not catchable not displayed, not catchable
ignore = false displayed, not catchable not displayed, catchable

It’s controled by the settings in the config.php files:

$configuration['error']['serverlog'] = true;

Set to true to use the server system log facility (i.e. “error_log”)

$configuration['error']['file_log_dir'] = 'write/logs/';

The folder location where to written our own logs (relative to the installation root)

$configuration['error']['email_critical'] = '';

Email to which we should send error messages

$configuration['error']['display'] = true;

Should we display error in the user’s browser window?

$configuration['error']['ignore_notices'] = false;

If this is true, the error handler will NOT handle notices, which may lead to your site being broken

$configuration['error']['ignore_warnings'] = false;

If this is true, the error handler will NOT handle warnings, which may lead to your site being broken

$configuration['error']['warningsAreFatal'] = true;

If true, a warning will be handled as an exception (and stops the cycle if not handled)

$configuration['error']['noticesAreFatal'] = false;

If true, a notice will be handled as an exception (and stops the cycle if not handled). If both this and ‘ignore_notices’ are false, and ‘display_errors’ is true, an inline notice message will be included in the page

$configuration['error']['mask'] = E_ALL; 

You should change to E_ALL | E_STRICT to be clean

$configuration['debug']['enable'] = true;

Enable or disable the debug subsystem globally

$configuration['debug']['level'] = 4; 
// 	DEBUG = 4;INFO = 3;WARN = 2;ERROR = 1;LOG = 0;

Set the level up to which the messages will be visible

$configuration['debug']['domains'] = array('*');
$configuration['debug']['domains'] = array('QUERY%MY*', 'MY_*');

List the debug domains to activate (see below)

$configuration['development'] = true;

Set to true if the code is under development

$configuration['production'] = false;

Set to true on a production site

Usage

Let’s see how we can actually use our little debugger.

Sending data to the conduits

Basic usage is very simple: just send a string to the log() method:

$this->log("Hello, console");

This method is defined in PHPDS_dependant so pretty much any code can access it.

Domains

All data sent thought the conduits are tagged with a semantic domain, such as “db” or “user”, so only the data you want to study are actually sent. The default behavior is to use the class name (with the PHPDS_ prefix riped off).

For example:

$configuration['debug']['domains'] = array('MY_*');
class MY_class extends PHPDS_dependant
{
    public do_something()
    {
        $this->log('Doing something');
    }
}

For you own classes, you can change it to anything you fancy, maybe having something adaptative. Take a look at what PHPDS_query does:

public function debugInstance($domain = null)
	{
		return parent::debugInstance(empty($domain) ? 'QUERY%'.get_class($this): $domaine);
	}

debug instances

Almost every object using the debug has a private debug instance ; this is mostly done to allow domain filtering, but you can override the debugInstance() method to provide your own customized debug instance or just customize the domain, like the Query system does.

Conduits

Data sent inside the debugger can be broadcast to various locations, depending on your configuration. Here are the default conduits available.

Display

This is the most detailed way of displaying errors, and it’s mostly used when the site is under development. It will display as much information as possible, including backtrace and code fragments.

Can be enabled (true) or disabled (false).

$configuration['error']['display_errors'] = true;

FirePHP

Used only when developing, FirePHP is very clever way to debug a webpage. It’s a plugin for Firebug which display some debug information sent along with the page (but not inside the page) by PHPDevShell. You can use it to study dynamic debug data without disturbing the page.

Can be enabled (true) or disabled (false).

$configuration['error']['firePHP'] = false;

Log file

This is the traditional conduit: writing textual data into a flat text file. Useful to keep hidden traces of a production site, but not interactive and very limited in the complexity of the data stored.

You can choose any file you have write access to.

$configuration['error']['file_log_dir'] = 'write/logs/';

Mail

A way to be alerted when something goes wrong. Should be used only for production site, and for important errors.

You can set the recipient of the emails.

$configuration['error']['email_critical'] = 'yourmail@phpdevshell.org';

Early debug

Even if PHPDevShell’s error and exception handler is installed early in the cycle, everything executed prior to this point cannot, obviously, be handled that way. To help catching error in this first part of the cycle a very limited debug channel is available by setting the global variable $early_debug to true. In that case, anything set to PHPDS->log() will be output to the web server’s error log (via error_log() ), until the normal handlers are set.

See also:
Suggestions on error

Feedback

Was this helpful?

Yes No
You indicated this topic was not helpful to you ...
Could you please leave a comment telling us why? Thank you!
Thanks for your feedback.

Post your comment on this topic.

Post Comment