Tach!
error_reporting(NULL); // I have my own ...!!!
Abgesehen davon, dass der Wert ein Integer sein sollte, also 0 statt NULL korrekter wäre, schaltest du damit nur nebenbei die Fehlermeldungen aus. Besser wäre ein ini_set('display_errors', 0); Selbst wenn du deine eigene Fehlermeldungsroutine verwendest, solltest du den error_reporting-Wert auf != 0 lassen. Egal welchen Wert du einstellst, ein eigener Error-Handler wird immer aufgerufen. Mit einem parameterlosen Aufruf von error_reporting() bekommt man (darin) diesen eingestellten Wert zurückgeliefert. Ausnahme ist ein vorangestelltes @, das dann dafür sorgt, dass 0 zurückgeliefert wird. Somit hat man in einem eigenen Error-Handler die Möglichkeit zwischen gewollter Unterdrückung und nicht behandelten Fehlern zu unterscheiden. Ein generelles 0 verhindert diese Unterscheidungsmöglichkeit.
class MyException extends Exception{
public function __construct($message = '', $trace = array()){
$default = array(
'trace' => 1,
'file' => $this->getFile(),
'line' => $this->getLine(),
);
$this->TRACE = array_merge($default, $trace);
$this->MESSAGE = $message;
}
public function getMyMessage(){
if($this->TRACE['trace'] == 1){
return sprintf("%s at %s, line %u", $this->MESSAGE, $this->TRACE['file'], $this->TRACE['line']);
}
else{
return $this->MESSAGE;
}
}
}
Du erweiterst die Standard-Klasse Exception, nutzt dann aber komplett eigene Eigenschaften und eine Ausgabemethode, anstatt die vorhandenen Mitglieder zu nutzen beziehungsweise zu überschreiben. Warum? Warum lässt du dann nicht gleich Exception unverwendet?
Zudem bekommst du auf diese Weise in $this->TRACE['line'] ohne die Übergabe der error_get_last()-Werte mit dem $this->getLine() die Zeile des MyException-Wurfs, womit dann diese Information nicht mehr sinnvoll ist.
$x .= 1; // Provoziere eine NOTICE
if(error_get_last()){
$eo = (object)error_get_last();
throw new MyException($eo->message, array('trace' => 1, 'file' => $eo->file, 'line' => $eo->line));
Na das ist ja auch unnötig umständlich. So musst du explizit nach aufgetretenen Fehlern fragen und dann kommen drei Zeilen nur zum Werfen. Dazu noch der doppelte Aufruf von error_get_last(), nur weil dir die Array-Schreibweise nicht gefällt. Sonst reichte ein
if ($eo = error_get_last()) {
Aber wie gesagt, es geht viel einfacher, wenn man die eingebauten Mechanismen nutzte.
class ErrorException extends Exception {
protected $context = array();
public function __construct($no, $msg, $file, $line, $context){
parent::__construct($msg, $no);
$this->file = $file; // Datei und Zeile setzen, sonst sind das die Werte vom throw im ErrorHandler
$this->line = $line;
$this->context = $context;
}
public static function ErrorHandler($no, $msg, $file, $line, $context) {
if (error_reporting())
throw new ExException($no, $msg, $file, $line, $context);
return true;
}
}
set_error_handler("ErrorException::ErrorHandler");
ErrorException nutzt die Mitglieder der Elternklasse. Lediglich der (Variablen-)Kontext kommt angedeuteterweise hinzu. Außerdem wird ein eigener Error-Handler aktiviert, der im Falle eines Falles ohne große Umstände von PHP selbst angesprungen wird.
try {
$x .= 1; // Provoziere eine NOTICE
print "Alles ist gut gegangen\n";
} catch (Exception $e) {
echo "Exception: ", $e;
}
So einfach kann es gehen. Wenn man mal keine Exception bekommen mag, dann kommt ein @ vor die potentiell fehlerwerfende Zeile. Die Ausgabe ist derzeit ein Exception-Trace. Geändert werden kann das durch Überschreiben von __toString().
dedlfix.