Пользовательский класс обработчика ошибок PHP протоколирование / отображение повторяющихся ошибок

#php #custom-error-handling

#php #пользовательская обработка ошибок

Вопрос:

Это первый раз, когда я использовал пользовательскую обработку ошибок и решил пойти по пути создания класса. В настоящее время это работает, но с побочными эффектами.

текущие значения ini:

 error_log = errors.log
display_errors = 0
log_errors = 1
  

Строка кода PHP:

 include('fakefile.php');
  

Сгенерирована ошибка:

 WARNING:  
    Code: 2
    Message: include(fakefile.php): failed to open stream: No such file or directory
    File: F:laragonwwwprojectsJLDesignNetworkindex.php
    Line: 71

WARNING:  
    Code: 2
    Message: include(): Failed opening 'fakefile.php' for inclusion (include_path='.;F:/laragon/etc/php/pear')
    File: F:laragonwwwprojectsJLDesignNetworkindex.php
    Line: 71
  

error_handler.class.php

 class ErrorHandler
{
    private $mailable = array(E_ERROR, E_USER_ERROR, E_USER_WARNING, E_WARNING);
    private $friendlyMsg = "We have encountered an unexpected error. The administrator has been notified. Please check back later.";
    private $logfile = null;
    private $techMail = null;
    private $mute = false;
    private $debug = false;
    private $details = null;
        
    function __construct($logfile=null, $techMail=null, $mute=false, $debug=false)
    {
        $this->logfile = $logfile; // should check to see if file exists
        $this->techMail = $techMail;  // should verify email is in valid format
        $this->mute = $mute;
        $this->debug = $debug;
        
        ini_set('error_log', $logfile);
        set_error_handler(array($this, 'customHandler'));
    }
    
    public function customHandler($errno, $errstr, $errfi, $errli)
    {
        $this->logstr = json_encode([
            "datetime" => date(DATE_RFC2822),
            "error" => [
                "code" => $errno,
                "file" => $errfi,
                "line" => $errli,
                "msg" => $errstr
            ]
        ],
        JSON_FORCE_OBJECT amp; JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP | JSON_UNESCAPED_UNICODE);
            
        $this->details = array($errno, $errstr, $errfi, $errli);
        $this->response();
        
        if(in_array($errno, $this->mailable)): $this->sendMail(); endif;
    }
        
    private function response() 
    {
        error_log(
            $this->logstr. PHP_EOL,
            3,
            $this->logfile
        );
            
        $display = sprintf(
            "tCode: %dntMessage: %sntFile: %sntLine: %d</pre>", 
            $this->details[0],
            $this->details[1],
            $this->details[2],
            $this->details[3]
        );
            
        // display an error message; shutdown if needed
        switch($this->details[0]):
            case E_USER_ERROR:
            case E_ERROR:
                $str = $this->debug ? "<pre><b>FATAL:</b> <br>" . $display : $this->friendlyMsg;
                break;
            case E_USER_WARNING:
            case E_WARNING:
                $str = $this->debug ? "<pre><b>WARNING:</b>  <br>" . $display  : $this->friendlyMsg;
                break;
            case E_USER_NOTICE:
            case E_NOTICE:
                $str = $this->debug ? "<pre><b>NOTICE:</b>  <br>" . $display  : $this->friendlyMsg;
                break;
            default :
                // do nothing
                break;
        endswitch;
            
        if(!$this->mute): echo $str; endif;
    }
        
    private function sendMail()
    {
        $html = sprintf("<h3>An error has occurred!</h3><hr>The following error was recently logged: <pre>%s</pre>", print_r(json_decode($this->logstr),true));
        /*error_log(
            $html,
            1,
            $this->techMail,
            'Content-type: text/html; charset=iso-8859-1'
        );*/
    }
}
    
$eh = new ErrorHandler('errors.log', 'someone@somewhere.net', false, true);
  

Мой вопрос заключается в следующем -> Почему ошибка включения регистрируется и отображается (на экране) дважды?

Пожалуйста, имейте в виду, что это не работает и все еще находится в стадии разработки.

Комментарии:

1. Ну, я бы сказал, что вы отправляете его дважды с error_log помощью amp; echo в методе ответа. Вы пытались включить свой mute атрибут, чтобы увидеть, отображается ли он только один раз?

2. Я не верю, что это проблема, потому что деление на ноль отображается только один раз. В то время как ошибка включения отображается дважды.