Klaus: OOP:Error Handler-Klassenvariable in statische Methode übergeben

Hallo Forum,

ich bin leider noch ein Neuling in OOP-Programmierung und versuche Momentan eine "Error Handler"-Klasse zu schreiben. Nun hab ich das Problem, dass man bei der Anmeldung der Funktionsnamen nur statische Methoden verwenden kann.

  
<?php  
//Anmeldung der Methdonnamen  
set_error_handler('errorHandler');  
?>  

Da ich meiner Klasse aber die Pfadangabe variabel angeben kann, hab ich jetzt das Problem, dass ich diese nicht der statischen Methode übergeben kann, zumindest wüsste ich jetzt nicht wie. Ich zeig mal einen kleinen Auszug aus der Klasse mit den relevanten Methoden.

  
<?php  
class C_errorHandler {  
   /*** VARS ***/  
      private $errorFilePath = '';  
  
   /*** METHDOS ***/  
      public function errorHandler($errno, $errstr, $errorFile, $errline) {  
          //Hier benötige ich jetzt die $errorFilePath variable  
          //ich kann sie leider nicht auf statisch setzten, da ich sie ja noch im  
          //nachhinein ja noch initialisieren will  
      }  
}//END_CLASS  
?>  

Gibt es hier eine Möglichkeit die Variable an die statische Methode zu übergeben oder bin ich generell auf dem falschen Dampfer. Über einen Lösungsvorschlag oder einen Ansatz wie man die Klasse richtig schreiben könnte, wäre ich euch sehr verbunden. Hier nochmal die gesamte Klasse, unter der Klasse befindet sich noch normaler ausführbarer Code um die Klasse zu testen.

  
class C_errorHandler {  
   /*** VARS ***/  
      private $errorFilePath = '';  
      private $errorLogFileName = '';  
      /* Nicht für die ini sondern für eine echo Ausgabe */  
      private $displayError = '';  
			  
   /*** MAGIC-METHODS ***/  
      public function __construct(){  
	$this->setDefaultConfig();  
	$this->initErrorLogFile();  
	$this->initErrorReporting();  
      }//END_FUNC  
			  
      private function __clone(){}  
		  
   /*** METHODS ***/  
      private function setDefaultConfig() {  
	$this->errorFilePath = dirname(__FILE__).'\\';  
	$this->errorLogFileName = 'errorLog.log';  
	$this->displayError = false;  
      }//END_FUNC  
			  
      private function initErrorLogFile() {  
        if (!file_exists($this->errorFilePath.$this->errorLogFileName)) {  
	  $handle = fopen($this->errorFilePath.$this->errorLogFileName, "a+");  
	  fclose($handle);  
	}//END_IF  
      }//END_FUNC  
			  
      private function initErrorReporting() {  
	error_reporting(E_ALL | E_STRICT);  
	ini_set('display_errors', false);  
      }//END_FUNC  
			  
      public function configErrorHandler($errorFilePath, $errorFileName,$displayErrorsOnScreen ) {  
	$errorFilePath .= '\\';  
	if( !ctype_alpha($errorFileName) )  
	   return false;  
           $errorFileName .= '.log';  
				  
	if( !file_exists($errorFilePath) )  
	   return false;  
	if( !is_bool($displayErrorsOnScreen) )  
	   return false;  
				  
	$this->errorFilePath = $errorFilePath;  
	$this->errorLogFileName = $errorFileName;  
	$this->displayError = $displayErrorsOnScreen;  
      }//END_FUNC  
			  
      /*  
       * Ich weiß das $this bei statischen Methoden nicht funktionieren,  
       * hab es vorher ohne statiche Methoden probiert.  
       */  
      public static function errorHandler($errno, $errstr, $errorFile, $errline) {  
	$message = '';  
	switch ($errno) {  
		case E_ERROR:  
		/* no Fatal here */  
		case E_NOTICE:  
			$message = '---NOTICE------------------------------------'."<br/>\n";  
			$message .= 'Date: '.date("d.m.Y h:i:s")."<br/>\n";  
			$message .= 'File: '.$errorFile. ' - Line: '.$errline."<br/>\n";  
			$message .= $errstr."<br/>\n";  
			$message .= '--------------------------------------------'."<br/>\n";  
			error_log ($message, 3,  $this->errorFilePath.$this->errorLogFileName);  
		break;  
		case E_WARNING:  
			$message = '---WARNING------------------------------------'."<br/>\n";  
			$message .= 'Date: '.date("d.m.Y h:i:s")."<br/>\n";  
			$message .= 'File: '.$errorFile. ' - Line: '.$errline."<br/>\n";  
			$message .= $errstr."<br/>\n";  
			$message .= '---------------------------------------------'."<br/>\n";  
			error_log ($message, 3,  $this->errorFilePath.$this->errorLogFileName);  
		break;  
		default:  
			$message = '---Unkown error type-------------------------'."<br/>\n";  
			$message .= 'Date: '.date("d.m.Y h:i:s")."<br/>\n";  
			$message .= 'File: '.$errorFile. ' - Line: '.$errline."<br/>\n";  
			$message .= $errstr."<br/>\n";  
			$message .= '--------------------------------------------'."<br/>\n";  
			error_log ($message, 3,  $this->errorFilePath.$this->errorLogFileName);  
		break;  
	}  
	if( $this->displayError )  
		echo $message;  
     }//END_FUNC  
			  
     public static function handleShutdown() {  
	$error = error_get_last();  
	if($error !== NULL) {  
		$message = '---FATAL [SHUTDOWN]--------------------------'."<br/>\n";  
		$message .= 'Date: '.date("d.m.Y h:i:s")."<br/>\n";  
		$message .= 'File: '.$error['file']. ' - Line: '.$error['line']."<br/>\n";  
		$message .= $error['message']."<br/>\n";  
		$message .= '--------------------------------------------'."<br/>\n";  
		echo $message;  
		error_log ($message, 3,  $this->errorFilePath.$this->errorLogFileName);  
	} else {  
		$message = '---FATAL [SHUTDOWN]--------------------------'."<br/>\n";  
		$message .= 'get no Error';  
		$message .= '--------------------------------------------'."<br/>\n";  
	}  
      }//END_FUNC  
}//END_CLASS  
  
	$a = new C_errorHandler();  
	$a->configErrorHandler(dirname(__FILE__), 'error', true);  
	set_error_handler('C_errorHandler::errorHandler');  
	register_shutdown_function('C_errorHandler::handleShutdown');  
	  
	echo $dsf;  

  1. Tach!

    ich bin leider noch ein Neuling in OOP-Programmierung und versuche Momentan eine "Error Handler"-Klasse zu schreiben.

    Ein Error Handler ist im einfachen Fall ein einmaliges Gebilde. Von dem braucht man keine Instanz. Also tut es eine Klasse mit statischen Mitgliedern. Es sei denn, du hast vor, den Error Handler an die jeweiligen Fehler verursachenden Elemente durchzureichen, weil du gern für jeden Programmteil ein eigenes Logging haben möchtest. In deinem Fall gehts dir aber darum, den Standard-PHP-Handler zu ersetzen. Das ist eine quasi statische Funktion und da tut es eine statische Klasse.

    Nun hab ich das Problem, dass man bei der Anmeldung der Funktionsnamen nur statische Methoden verwenden kann.

    //Anmeldung der Methdonnamen
    set_error_handler('errorHandler');

      
    Nein, set\_error\_handler() möchte etwas vom [Pseudo-Typ callable](http://de2.php.net/manual/en/language.types.callable.php) übergeben bekommen. Das kann alles mögliche sein, vom Funktionsnamen über statische und Objektmethoden bis zu anonymen Funktionen.  
      
    
    > Da ich meiner Klasse aber die Pfadangabe variabel angeben kann, hab ich jetzt das Problem, dass ich diese nicht der statischen Methode übergeben kann, zumindest wüsste ich jetzt nicht wie.  
      
    Du brauchst keien Instanz. Eine Klasse kann auch statiche Eigenschaften haben. (Für sttiche Eigenschaften und Methoden gibt es das Schlüsselwort static. Das wird auch angemeckert, wenn man static weglässt auf auf solche Eigenschaften statisch zugreift. Error\_reporting auf E\_ALL stellen und gegebenenfalls noch E\_STRICT hinzufügen.) Einer statische Eigenschaft kann man von außen Werte setzen, wenn sie public ist. Es geht auch ein statischer Setter, aber der ist im Prinzip sinnlos, wenn man in ihm auch nichts weiter macht, als den Wert zu setzen.  
      
    
    > Gibt es hier eine Möglichkeit die Variable an die statische Methode zu übergeben oder bin ich generell auf dem falschen Dampfer.  
      
    An den Error-Handler nicht, denn der wird vom System aus aufgerufen und dieser Aufruf ist nicht konfigurierbar.  
      
    
    > Über einen Lösungsvorschlag oder einen Ansatz wie man die Klasse richtig schreiben könnte, wäre ich euch sehr verbunden. Hier nochmal die gesamte Klasse, unter der Klasse befindet sich noch normaler ausführbarer Code um die Klasse zu testen.  
      
    Hab ich mir jetzt nicht im einzelnen angeschaut. Wenn du aber eine Instanz haben möchtest und nicht alles statisch, dann kannst du die Instanz auch privat erzeugen, von einer statische Initialisierungsfunktion aus. Der kannst du auch den Pfadwert übergeben.  
      
      
    dedlfix.
    
    1. Hallo dedlfix,

      vielen Dank für deine Antwort. Ich habe das Problem nun über statische Eigenschaften gelöst, dies habe ich zwar schon vorher probiert, jedoch habe ich die statischen Variablen falsch angesprochen.
      Anstatt

        
      self::staticVar  
      //habe ich die statische Variable über  
      staticVar  
      //angesprochen, was - wie ich gemerkt habe - natürlich nicht funktionieren kann.  
      
      

      An den Error-Handler nicht, denn der wird vom System aus aufgerufen und dieser Aufruf ist nicht konfigurierbar.

      Da eben der Aufruf nicht konfigurierbar ist, macht eine Instanz natürlich keinen Sinn, vielen Dank für diese Information. Da ich aber die Fehlerausgaben je nach Benutzerrecht ausgeben wollte, werde ich diese einfach in einem XML-File mit loggen um sie gezielt auszugeben.

      Vielen Dank für deine kompetente Antwort. Wenn ich die Klasse samt Logg-Funktion fertig habe werde ich sie noch Posten.

      Gruß Klaus