#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. Я не верю, что это проблема, потому что деление на ноль отображается только один раз. В то время как ошибка включения отображается дважды.