1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
| <?php
class MultipleErrorHandler {
// List every observer for each $errno
protected static $observers = array();
// Reference each callback function
protected static $callbacks = array();
// List all the catchable errors
protected static $catchable_errors = array();
// Attach an callback function as error handler
// The index return is needed to Detach the callback handler
public static function Attach($callback, $errno = E_ALL) {
static $count = 1;
self::$callbacks[$count] = $callback;
foreach(self::get_catchable_errors() as $catchable) {
if (($errno & $catchable) == $catchable) {
array_unshift(self::$observers[$catchable], $count);
}
}
return $count++;
}
// Detach a callback function from error handling
// Needs the index returned by Attach()
public static function Detach($index, $errno = E_ALL) {
foreach(self::get_catchable_errors() as $catchable) {
if (($errno & $catchable) == $catchable) {
$key = array_search($index, self::$observers[$catchable]);
if (false !== $key) {
unset(self::$observers[$catchable][$key]);
}
}
}
}
// Runs the MultipleErrorHandler
public static function Run($old_error_level = E_ALL) {
$old_error_handler = set_error_handler(array(__CLASS__, 'Notify'));
// If an old handler was attached, keep it in the error handling process
if ($old_error_handler !== null && $old_error_level) {
self::Attach($old_error_handler, $old_error_level);
}
return $old_error_handler;
}
// Custom error handler used by the class
public static function Notify($errno, $errstr, $errfile, $errline, $errcontext) {
$stop_propagation = false;
foreach(self::get_catchable_errors() as $catchable) {
if (($errno & $catchable) == $errno) {
foreach(self::$observers[$errno] as $callback) {
$stop_propagation = (true === call_user_func(self::$callbacks[$callback], $errno, $errstr, $errfile, $errline, $errcontext)) || $stop_propagation;
}
}
}
return $stop_propagation;
}
// Returns all catchable errors as an array
public static function get_catchable_errors() {
if (empty(self::$catchable_errors)) {
self::$catchable_errors = array(E_WARNING,E_PARSE,E_NOTICE,E_USER_ERROR,E_USER_WARNING,E_USER_NOTICE);
foreach(array('E_STRICT','E_RECOVERABLE_ERROR','E_DEPRECATED','E_USER_DEPRECATED') as $constant) {
defined($constant) && self::$catchable_errors[] = constant($constant);
}
foreach(self::$catchable_errors as $type) {
self::$observers[$type] = array();
}
}
return self::$catchable_errors;
}
}
function test_handler($errno, $errstr, $errfile, $errline, $errcontext) {
echo 'test ok';
return false;
}
function test_handler_2($errno, $errstr, $errfile, $errline, $errcontext) {
echo 'test autre';
return false;
}
MultipleErrorHandler::Run(); // Don't reattach the old error handler
$index = MultipleErrorHandler::Attach('test_handler', E_WARNING);
$index = MultipleErrorHandler::Attach('test_handler_2', E_WARNING);
2/0; |
Partager