
Originally Posted by
sleepeasy
True, however, to my knowledge there's no way to prevent an error handler being called by an @supressed error, because the error type produced is the same as if the @ wasn't present
Not true. Errors generated where @ was used get the severity rating of 0. Here's a simple debug handler that takes advantage of that fact:
PHP Code:
/**
* Error handler, providing rigorous backtrace information.
* @param int error type
* @param string error message
* @param string file name
* @param string line number
*/
function ErrorHandler ($error_type, $error_message, $file, $line)
{
static $error_types = array
(
1 => 'E_ERROR', 2 => 'E_WARNING',
4 => 'E_PARSE', 8 => 'E_NOTICE',
16 => 'E_CORE_ERROR', 32 => 'E_CORE_WARNING',
64 => 'E_COMPILE_ERROR', 128 => 'E_COMPILE_WARNING',
256 => 'E_USER_ERROR', 512 => 'E_USER_WARNING',
1024 => 'E_USER_NOTICE', 2047 => 'E_ALL',
2048 => 'E_STRICT'
);
/**
* Check error type against error reporting level. @ is always ignored.
*/
if (($error_type != 0) && ($error_type & ini_get('error_reporting')))
{
echo "<strong>".$error_types[$error_type]."</strong>: {$error_message}<br />\n";
echo "In <strong>$file</strong> ";
echo "on line <strong>$line</strong><br />\n";
echo "<p>Backtrace:</p><pre>";
$backtrace = debug_backtrace();
// First is always ErrorHandler, skip it
array_shift($backtrace);
$i = -1;
foreach ($backtrace as $trace)
{
$args = array();
if (isset($trace['args']))
{
foreach ($trace['args'] as $a)
{
switch (gettype($a))
{
case 'integer':
case 'double':
$args[] = $a;
break;
case 'string':
$a = htmlspecialchars(substr($a, 0, 64)).((strlen($a) > 64) ? '&hellip' : '');
$args[] = "\"$a\"";
break;
case 'array':
$args[] = 'Array('.count($a).')';
break;
case 'object':
$args[] = 'Object('.get_class($a).')';
break;
case 'resource':
$args[] = 'Resource('.strstr($a, '#').')';
break;
case 'boolean':
$args[] = $a ? 'True' : 'False';
break;
case 'NULL':
$args[] = 'NULL';
break;
default:
$args[] = 'UNKNOWN';
}
}
}
echo '#'.++$i.' ';
echo $trace['file'].'('.$trace['line'].'): ';
echo (isset($trace['class']) ? $trace['class'].$trace['type'] : '');
echo $trace['function'].'('.implode(', ',$args).')';
echo "\n";
}
echo '#'.++$i." {main}</pre>";
exit;
}
}
Bookmarks