| @copyright 2007-2026 (c) AVE.cms | @link https://ave-cms.ru | @version 3.3 */ namespace App\Common; defined("BASEPATH") || die ('Direct access to this location is not allowed.'); use App\Helpers\Debug; use App\Helpers\File; class Errors { /** @var bool Защита от рекурсии (ошибка внутри обработчика) */ protected static $handling = false; public function __construct () { if (PHP_DEBUGGING_FILE) { ini_set('display_errors', 'Off'); set_error_handler([$this, 'scriptError'], E_ALL); register_shutdown_function([$this, 'shutDown']); } } /** * Обработчик не-фатальных ошибок. * Уважает @-подавление и error_reporting; всегда пишет в лог; * «красивый» блок рендерит только в dev и не в AJAX/JSON. */ public function scriptError ($errno, $errstr, $errfile, $errline) { // Уважать @ и текущий уровень error_reporting if (! (error_reporting() & $errno)) { return false; } $severity = self::severityName($errno); $this->logError($severity, $errstr, $errfile, $errline); // HTML-блок — только в режиме отладки и не в AJAX/JSON // (иначе разметка попадёт в JSON-ответ и сломает его) if (defined('PHP_DEBUGGING') && PHP_DEBUGGING && ! self::isAjax()) { echo $this->renderBox($severity, $errno, $errstr, $errfile, $errline); } return true; } /** * Обработчик фатальных ошибок при завершении скрипта. */ public function shutDown () { if (! $error = error_get_last()) { return; } $fatalTypes = [ E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING, E_USER_ERROR, E_RECOVERABLE_ERROR, ]; if (! in_array($error['type'], $fatalTypes, true)) { return; } $severity = self::severityName($error['type']); $this->logError($severity, $error['message'], $error['file'], $error['line']); if (PHP_SAPI === 'cli') { fwrite(STDERR, 'Fatal: ' . $error['message'] . ' (' . $error['file'] . ':' . $error['line'] . ")\n"); return; } if (! headers_sent()) { header('HTTP/1.1 500 Internal Server Error'); } if (self::isAjax()) { if (! headers_sent()) { header('Content-Type: application/json; charset=UTF-8'); } echo json_encode(['success' => false, 'error' => 'Внутренняя ошибка сервера']); return; } if (defined('PHP_DEBUGGING') && PHP_DEBUGGING) { echo $this->renderBox($severity, $error['type'], $error['message'], $error['file'], $error['line']); return; } echo '' . '
'; $out .= '[' . $errno . '] ' . File::cutRootPathAll($errstr); $out .= ''; $out .= '