Hmm... das erscheint mir umständlich. Ich hatte da eher an was Gegenteiliges gedacht.)
Beispiel (reduziert):
<?php
class NoticeException extends ErrorException {}
class WarningException extends ErrorException {}
class Errors
{
private $severity = array();
public $onFatal = NULL;
public function __construct($severity = E_ALL)
{
error_reporting(E_ALL);
$this->setDisplay(FALSE);
set_error_handler(array($this, 'onError'), E_ALL);
register_shutdown_function(array($this, 'onShutdown'));
$this->setSeverity($severity);
}
public function __destruct()
{
restore_error_handler();
$this->onFatal = NULL;
}
public function setDisplay($enable)
{
ini_set('display_errors', (bool)$enable);
return $this;
}
public function getDisplay()
{
return (bool)ini_get('display_errors');
}
public function setSeverity($severity)
{
$notices = E_NOTICE | E_USER_NOTICE | E_STRICT | E_DEPRECATED | E_USER_DEPRECATED;
$warnings = E_WARNING | E_USER_WARNING;
switch (0|$severity) {
case E_NOTICE:
$severity = $notices;
break;
case E_WARNING:
$severity = E_ALL ^ ($notices);
break;
default:
$severity |= E_ALL ^ ($notices | $warnings);
break;
}
array_push($this->severity, $severity);
return $this;
}
public function getSeverity()
{
return end($this->severity);
}
public function restoreSeverity()
{
if (count($this->severity) > 1) {
array_pop($this->severity);
}
return $this;
}
public function onError($severity, $message, $filepath, $line)
{
switch ($this->maskSeverity($severity)) {
case 0:
return 0 !== (error_reporting() & $severity);
case E_NOTICE:
case E_USER_NOTICE:
case E_STRICT:
case E_DEPRECATED:
case E_USER_DEPRECATED:
throw new NoticeException($message, 2, $severity, $filepath, $line);
case E_WARNING:
case E_USER_WARNING:
throw new WarningException($message, 1, $severity, $filepath, $line);
default:
throw new ErrorException($message, 0, $severity, $filepath, $line);
}
}
public function onShutdown()
{
$error = error_get_last();
if ($error && is_callable($this->onFatal)) {
call_user_func_array($this->onFatal, $error);
}
}
protected function maskSeverity($severity)
{
return $severity & $this->getSeverity();
}
}
$errors = new Errors;
try {
$a = $b; // undefined
} catch(Exception $e) {
echo get_class($e), ' ', $e->getMessage(), PHP_EOL;
}
$errors->setSeverity(E_WARNING);
try {
$c = $a[WTF]; // undefined - ignored
fopen('WTF', 'r'); // warning thrown
} catch(Exception $e) {
echo get_class($e), ' ', $e->getMessage(), PHP_EOL;
}
try {
trigger_error('The current user sucks', E_USER_ERROR);
} catch(Exception $e) {
echo get_class($e), ' ', $e->getMessage(), PHP_EOL;
}
$errors->restoreSeverity();
$errors->onFatal = function($severity, $message) {
echo 'FATAL: ', $message, PHP_EOL;
};
// uncatchable fatal error -> shutdown
try {
~FALSE;
} catch(Exception $e) {
echo $e->getMessage(), PHP_EOL;
}