zehbaeh: Warnungen und Notizen in den Status einer Exception erheben

Beitrag lesen

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;  
}