type = $type;
$this->message = $message;
$this->file = $file;
$this->line = $line;
$this->backtrace = $backtrace;
}
/**
* Get an associative array describing the error
*/
function getArray() {
return array( 'type' => $this->type,
'message' => $this->message,
'file' => $this->file,
'line' => $this->line );
}
/**
* Get an html formatted version of the error
*/
function getHtml() {
switch ($this->type) {
case E_USER_ERROR: return "
\nFatal error: {$this->message} in {$this->file} on line {$this->line}
\n";
case E_WARNING:
case E_USER_WARNING: return "
\nWarning: {$this->message} in {$this->file} on line {$this->line}
\n";
case E_NOTICE:
case E_USER_NOTICE: return "
\nNotice: {$this->message} in {$this->file} on line {$this->line}
\n";
//default: return "
\nUnknown: {$this->message} in {$this->file} on line {$this->line}
\n";
}
}
/**
* Get the contents of debug_backtrace()
*/
function getBacktraceArray() {
return $this->backtrace;
}
/**
* Get an html formatted version of the debug backtrace
*/
function getBacktraceHtml() {
$buffer = '';
if (!empty($this->backtrace)) {
$buffer .= "Call stack:\n
\n";
foreach ($this->backtrace as $call) {
$function = $call['function'];
if (isset($call['class']))
$function = $call['class'] . $call['type'] . $function;
$arglist = array();
if (isset($call['args'])) {
foreach ($call['args'] as $arg) {
if (is_object($arg))
$arglist[] = 'object ' . get_class($arg);
else if (is_array($arg))
$arglist[] = 'Array(' . count($arg) . ')';
else
$arglist[] = "'$arg'";
}
}
$args = implode(', ', $arglist);
$buffer .= "- $function($args)";
if (isset($call['file'], $call['line']))
$buffer .= " in {$call['file']} on line {$call['line']}";
$buffer .= "
\n";
}
$buffer .= "
\n";
}
return $buffer;
}
}
/**
* Class to encapsulate error handling
*
* This class is created internally and should not need to be instanciated
* by the user.
*/
class FAErrorHandler {
var $handlers = array();
function FAErrorHandler() {
set_error_handler(array($this, 'handleError'));
}
function &getInstance() {
static $instance = NULL;
if ($instance == NULL) $instance = array(new FAErrorHandler);
return $instance[0];
}
function handleError($type, $message, $file, $line) {
$instance = &$this->getInstance();
if ($type & error_reporting()) {
$backtrace = array_slice(debug_backtrace(), 2);
$error = &new FAError($type, $message, $file, $line, $backtrace);
foreach ($instance->handlers as $handler) {
if (call_user_func($handler, $error))
break;
}
if (empty($instance->handlers)) {
$html = $error->getHtml() . $error->getBacktraceHtml();
if ($type & (E_ERROR | E_USER_ERROR))
die ($html);
echo $html;
}
}
}
function pushHandler($handler) {
if (is_array($handler) && method_exists($handler[0], $handler[1])) {
array_unshift($this->handlers, $handler);
} else if (function_exists($handler)) {
array_unshift($this->handlers, $handler);
} else {
trigger_error("Error handler function does not exist.", E_USER_WARNING);
}
}
function popHandler() {
array_shift($this->handlers);
}
}
/**
* Push an error handler onto the stack
*
* Error handling in filearts uses a stack-based mechanism to give scripts
* specialized error handling. A function can push a custom error handler
* onto the stack during the execution of some critical piece of code.
* After that code, it can pop it off the stack.
*
* Error handlers should be functions or class methods accepting a reference
* to a FAError object. If the error handler decides that it has handled
* the error, it can return true to prevent the error from propagating back
* down the error handler stack.
*
* @see FAError
* @see pop_error_handler
*/
function push_error_handler($handler) {
$instance = &FAErrorHandler::getInstance();
$instance->pushHandler($handler);
}
/**
* Pop the last error handler off the stack
*
* This function is used at the end of a block of code that needs special
* error treatment.
*
* @see push_error_handler
*/
function pop_error_handler() {
$instance = &FAErrorHandler::getInstance();
$instance->popHandler();
}
?>