1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
|
<?php
declare(strict_types=1);
namespace Error\EventListener;
use Psr\Log\LoggerInterface;
use Psr\Log\LogLevel;
final class ShutdownHandler
{
/**
* @var LoggerInterface
*/
private $logger;
/**
* @var array
*/
private $errorPriorityMap = [
E_NOTICE => LogLevel::NOTICE,
E_USER_NOTICE => LogLevel::NOTICE,
E_WARNING => LogLevel::WARNING,
E_CORE_WARNING => LogLevel::WARNING,
E_USER_WARNING => LogLevel::WARNING,
E_ERROR => LogLevel::ERROR,
E_USER_ERROR => LogLevel::ERROR,
E_CORE_ERROR => LogLevel::ERROR,
E_RECOVERABLE_ERROR => LogLevel::ERROR,
E_PARSE => LogLevel::ERROR,
E_COMPILE_ERROR => LogLevel::ERROR,
E_COMPILE_WARNING => LogLevel::ERROR,
E_STRICT => LogLevel::DEBUG,
E_DEPRECATED => LogLevel::DEBUG,
E_USER_DEPRECATED => LogLevel::DEBUG,
];
/**
* ShutdownHandler constructor.
*
* @param LoggerInterface $logger
*/
public function __construct(LoggerInterface $logger)
{
$this->logger = $logger;
}
public function __invoke()
{
$error = error_get_last();
if (null === $error || $error['type'] !== E_ERROR) {
return;
}
while (ob_get_level() > 0) {
ob_end_clean();
}
$chars = md5(uniqid('', true));
$errorReference = substr($chars, 2, 2).substr($chars, 12, 2).substr($chars, 26, 2);
$extras = [
'reference' => $errorReference,
'file' => $error['file'],
'line' => $error['line'],
];
$priority = $this->errorPriorityMap[$error['type']];
$this->logger->log($priority, $error['message'], $extras);
// set absolute path of the template to render (the shutdown method sometimes changes relative path).
$fatalTemplatePath = __DIR__.'/../../view/error/fatal.html';
// read content of file
$body = file_get_contents($fatalTemplatePath);
// inject error reference
$body = str_replace('%__ERROR_REFERENCE__%', 'Error Reference: '.$errorReference, $body);
echo $body;
exit(1);
}
} |
Partager