2016-11-01 12 views
1

Ich habe benutzerdefinierte Fehlerbehandlung (siehe unten) gemacht, die funktioniert gut. Ich habe die Methode add() hinzugefügt, die verwendet wird, um Fehler zu drucken und zu protokollieren. Grundsätzlich behandelt es alle von PHP registrierten Fehler.Korrekte Art, Fehlerzeile und Datei-Nr. mit debug_backtrace() in benutzerdefinierten Funktion, die benutzerdefinierte Fehlerhandle-Methode verwendet

Ich habe versucht, add_error() Funktion außerhalb der Klasse, für entwicklerfreundlichere Verwendung von Hinzufügen von Fehlern hinzuzufügen. Das Problem, das ich habe, ist, dass ich würde gerne die richtige Zeile & Datei von ihm bekommen, aber mit debug_backtrace() scheint zu kompliziert. Ich meine .. Es macht den Trick, aber es gibt Array von anderen unnötigen Sachen und ich versuchte, das Array zu filtern, um die Datei und Zeile, die der Fehler aufgerufen wurde, zurückgeben, aber ohne Glück.

Wenn ich nenne $ error-> add ('Test', 'Test') zum Beispiel aus load.php Datei, in der auf die Klassendatei fehler handle.php ist es enthalten ist, kehrt

C:\WebServer\www\projects\backend-framework\includes\error-handle.php:144: 
array (size=2) 
    0 => 
    array (size=7) 
     'file' => string 'C:\WebServer\www\projects\backend-framework\load.php' (length=52) 
     'line' => int 34 
     'function' => string 'add' (length=3) 
     'class' => string 'ErrorHandle' (length=11) 
     'object' => 
     object(ErrorHandle)[1] 
      public 'count' => int 0 
      public 'last_error' => null 
      public 'errors' => 
      array (size=0) 
       ... 
      public 'debug' => int 1 
      public 'report_errors' => int 1 
      public 'log_errors' => int 1 
     'type' => string '->' (length=2) 
     'args' => 
     array (size=2) 
      0 => string 'test' (length=5) 
      1 => string 'test' (length=5) 
    1 => 
    array (size=4) 
     'file' => string 'C:\WebServer\www\projects\backend-framework\index.php' (length=53) 
     'line' => int 2 
     'args' => 
     array (size=1) 
      0 => string 'C:\WebServer\www\projects\backend-framework\load.php' (length=52) 
     'function' => string 'require_once' (length=12) 

test: test in C:\WebServer\www\projects\backend-framework\index.php on line 2 

Wie Sie es zurück index.php statt load.php

sehen Bascially

, wenn ich rufe add_error() oder $ error-> add() Ich brauche & Linie die richtige Datei zu erhalten, wo die Funktion von aufgerufen wurde. Möglicherweise mit debug_backtrace() mit einigen erweiterten Filterung.

Ich bin dankbar für jede Anleitung oder Ideen, wie Sie dieses Ergebnis erhalten. Vielen Dank im Voraus!

CUSTOM Fehlerbehandlungsroutine:

<?php 
/** Custom error handle **/ 
class ErrorHandle { 
    public $count = 0; 
    public $last_error; 
    public $errors = array(); 
    public $debug; 
    public $report_errors; 
    public $log_errors; 

    function __construct($debug = false, $report_errors = false, $log_errors = true){ 
     // Set error report & log args 
     $this->debug = $debug; 
     $this->report_errors = $report_errors; 
     $this->log_errors = $log_errors; 

     // Setup error reporting & logging 
     $this->report_errors($this->report_errors); 
     $this->log_errors($this->log_errors); 


     // Register error handle 
     set_error_handler(array($this, 'error_handler')); 
     // Register fatal error handle 
     register_shutdown_function(array($this, 'fatal_error_handler')); 
    } 

    function error_handler($type, $message, $file, $line){ 
     $html_message = ''; 
     switch ($type) { 
      case E_ERROR: 
       $error_type = 'Runtime Error'; 
       break; 
      case E_WARNING: 
       $error_type = 'Runtime Warning'; 
       break; 
      case E_PARSE: 
       $error_type = 'Runtime Parse'; 
       break; 
      case E_NOTICE: 
       $error_type = 'Runtime Notice'; 
       break; 
      case E_CORE_ERROR: 
       $error_type = 'Core Error'; 
       break; 
      case E_CORE_WARNING: 
       $error_type = 'Core Warning'; 
       break; 
      case E_COMPILE_ERROR: 
       $error_type = 'Compile Error'; 
       break; 
      case E_COMPILE_WARNING: 
       $error_type = 'Compile Warning'; 
       break; 
      case E_USER_ERROR: 
       $error_type = 'User Error'; 
       break; 
      case E_USER_WARNING: 
       $error_type = 'User Warning'; 
       break; 
      case E_USER_NOTICE: 
       $error_type = 'User Notice'; 
       break; 
      case E_STRICT: 
       $error_type = 'PHP Suggestion'; 
       break; 
      case E_RECOVERABLE_ERROR: 
       $error_type = 'PHP Notice'; 
       break; 
      case E_DEPRECATED: 
       $error_type = 'PHP Warning'; 
       break; 
      case E_USER_DEPRECATED: 
       $error_type = 'PHP Deprecation'; 
       break; 
      default: 
       $error_type = 'Unknown'; 
     } 

     $this->add($error_type, $message, $file, $line); 
    } 

    // Fatal error handler 
    function fatal_error_handler() { 
     $last_error = error_get_last(); 

     if(in_array($last_error['type'],array(E_ERROR, E_CORE_ERROR, E_COMPILE_ERROR, E_USER_ERROR, E_RECOVERABLE_ERROR, E_CORE_WARNING, E_COMPILE_WARNING, E_PARSE))){ 
      $this->error_handler($last_error['type'], $last_error['message'], $last_error['file'], $last_error['line']); 
     } 

     die(); 
    } 

    // Turn ON/OFF display errors 
    function report_errors($bool=false){ 

     ini_set('display_startup_errors', 0); 
     ini_set('docref_root', 0); 
     ini_set('docref_ext', 0); 

     if($bool){ 
      error_reporting(999999999); 
      ini_set('error_reporting', 999999999); 
      ini_set('display_errors', 1); 

      ini_set('report_memleaks', 1); 
      ini_set('track_errors', 1); 
      ini_set('display_startup_errors', 1); 

      return true; 
     }else{ 
      error_reporting(0); 
      ini_set('error_reporting', 0); 
      ini_set('display_errors', 0); 

      return false; 
     } 
    } 

    function log_errors($bool){ 
     if($this->log_errors){ 
      ini_set("log_errors", 1); 
      ini_set("error_log", LOGS_DIR . 'php-error_' . date('d.m.y') . '.txt'); 
      return true; 
     } 
     return false; 
    } 

    function add($type, $message, $file = '', $line = 0){ 

     $html_message = ''; 
     $backtrace = debug_backtrace(); 


     if ($file == '') $file = $backtrace[1]['file']; 
     if ($line == 0) $line = $backtrace[1]['line']; 

     //var_dump($backtrace); 

     $error = array(
      'type'  => $type, 
      'message' => $message, 
      'file'  => $file, 
      'line'  => $line 
     ); 

     if(!in_multi_array($error, $this->errors)){ 
      $this->count++; 
      $this->errors[$this->count] = $error; 
      $this->last_error = $this->errors[$this->count]; 

      if($this->report_errors == true) echo $type . ': <strong>' . $message . '</strong> ' . '<i>in</i> <u>' . $file . '</u> <i>on line</i> <strong>' . $line . '</strong></i></br>'; 

      if($this->log_errors == true) error_log($type . ': ' . $message . ' in ' . $file . ' on line ' . $line); 
      return true; 
     } 
     return false; 
    } 

} 
?> 

Antwort

0

Okay, also machte ich eine kleine Arbeit um. Dies ist Methode von ErrorHandle Klasse:

 /** 
    * Report (print), Log error 
    * Use this function inside functions or methods. If you need 
    * need to add custom error outside - use global add_error() function. 
    * (This is because there is not yet a proper debug_backtrace method to use 
    * to return error FILE name & LINE number) properly!!! 
    */ 
    public function add($type, $message, $file = '', $line = 0){ 

     $html_message = ''; 

     /** 
     * WARNING! This is beta version 
     * If custom error is added, we need to backtrace it & filter the result to 
     * get accurate FILE name & LINE number. 
     */ 
     if($file == '' || $line == 0) : 

      $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); 

      // Filtering - if we find something to exclude, we remove it to get closer to actual file & line nr. 
      foreach ($backtrace as $key => $value) { 
       // The filter 
       if((isset($value) && strpos($value['file'], 'error-handle.php')) || (isset($value['class']) && $value['class'] == 'ErrorHandle' && $value['function'] == 'add')){ 
        array_splice($backtrace, $key, 1); 
       } 
      } 

      if ($file == '') $file = $backtrace[0]['file']; 
      if ($line == 0) $line = $backtrace[0]['line']; 

     endif; 


     $error = array(
      'type'  => $type, 
      'message' => $message, 
      'file'  => $file, 
      'line'  => $line 
     ); 

     // Let's check if we haven't stored the same error previously, so there's no dublication 
     if(!in_multi_array($error, $this->errors)){ 
      $this->count++; 
      $this->errors[$this->count] = $error; 
      $this->last_error = $this->errors[$this->count]; 

      // Report Error Message 
      if($this->report_errors) echo $type . ': <strong>' . $message . '</strong> ' . '<i>in</i> <u>' . $file . '</u> <i>on line</i> <strong>' . $line . '</strong></i></br>'; 
      // Log Error Message 
      if($this->log_errors) error_log($type . ': ' . $message . ' in ' . $file . ' on line ' . $line); 

      return true; 
     } 
     return false; 
    } 

Und außerhalb der Klasse I diese Funktion auch erstellt:

scheint
/** 
* Add error 
* Don't use this function inside functions or methods!!! 
* If you need to add error inside function or method - use $error->add() function. 
* (This is because there is not yet a proper debug_backtrace method to use 
* to return error FILE name & LINE number) properly!!! 
*/ 
function add_error($type, $message, $file = '', $line = 0){ 
    global $error; 
    return $error->add($type, $message, $file, $line); 
} 

Alles gut zu funktionieren. Versucht dies in verschiedenen Tiefen & Ebenen. ABER .. das einzige Problem, das ich keinen Weg finden kann zu beheben - $ error-> add() muss immer innerhalb der Funktionen & Methoden verwendet werden, während add_error() Funktion außerhalb (kann nicht sein verwendet in Funktionen & Methoden). Bin mir noch nicht sicher, warum, aber das ist etwas zu beginnen :)

1

Wie Sie es zurück index.php statt load.php

Es beide tatsächlich wieder sehen kann, ist es, dass Sie nur Greifen Sie auf $backtrace[1]['file'] zu, wenn es scheint, dass Sie tatsächlich $backtrace[0]['file'] möchten.

Ich denke, debug_backtrace macht viel mehr Sinn, wenn Sie berücksichtigen, dass die Tiefe berücksichtigt werden muss. Verwenden Sie das folgende Beispiel als Startpunkt:

Mit diesem können Sie experimentieren, um zu sehen, welche Tiefe Sie tatsächlich suchen. Natürlich hängt alles davon ab, wie Ihre Anwendung organisiert ist, so dass bestimmte Dateien unterschiedliche Tiefen haben können.

+0

Danke. Ich werde versuchen, darauf zu schauen. In der Zwischenzeit bin ich über diese Methode gekommen, die scheint auf Top-Level-Funktionen zu arbeiten. '$ dbt = debug_backtrace (DEBUG_BACKTRACE_IGNORE_ARGS, 2); $ aufrufer = isset ($ dbt [1] ['funktion'])? $ dbt [1] ['function']: null; ' Über Tiefen sprechen - das ist der Hauptgrund, warum ich über das Filtern nach ** debug_backtrace() nachgedacht habe ** –

Verwandte Themen