RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 957852
Accepted
Максим Н Епихин
Максим Н Епихин
Asked:2020-03-18 04:49:04 +0000 UTC2020-03-18 04:49:04 +0000 UTC 2020-03-18 04:49:04 +0000 UTC

如何处理 MVC PHP 错误?

  • 772

大家好。我正在为应用程序开发编写我的库。现在有一个关于如何处理错误和异常的严肃问题。决定使用记录错误、致命错误和异常的方法。我注意到一个奇怪的地方,set_error_handler即使它已经发送了标头,register_shutdown_function它也可以工作两次。现在的问题是我无法重定向到错误页面:. 该错误是专门在要检查的视图中引发的,即在渲染页面之后。Cannot modify header information - headers already sent by

通常,任务是显示包含详细信息的错误页面或不显示详细信息的错误页面。

如何解决重复错误的问题并在必要时重定向?

<?php

namespace Core;

use Helpers\Config;
use Helpers\File;
use Helpers\Url;

/**
 * Class ErrorHandler
 * Обработчик ошибок и исключений
 * @package Сore
 */
class ErrorHandler
{
    /**
     * @var array Константа ассоциаций кода ошибок к тексту
     */
    const ERRORS = [
        E_ERROR => 'ERROR',
        E_WARNING => 'WARNING',
        E_PARSE => 'PARSE',
        E_NOTICE => 'NOTICE',
        E_CORE_ERROR => 'CORE_ERROR',
        E_CORE_WARNING => 'CORE_WARNING',
        E_COMPILE_ERROR => 'COMPILE_ERROR',
        E_COMPILE_WARNING => 'COMPILE_WARNING',
        E_USER_ERROR => 'USER_ERROR',
        E_USER_WARNING => 'USER_WARNING',
        E_USER_NOTICE => 'USER_NOTICE',
        E_STRICT => 'STRICT',
        E_RECOVERABLE_ERROR => 'RECOVERABLE_ERROR',
        E_DEPRECATED => 'DEPRECATED',
        E_USER_DEPRECATED => 'USER_DEPRECATED',
    ];

    public static $status;

    /**
     * Регистрация методов управления ошибками и исключениями.
     * Включение отображения ошибок
     */
    public static function register()
    {
        ini_set('display_errors', 1);
        error_reporting(E_ALL);

        # Управление ошибками
        set_error_handler([__CLASS__, 'errorHandler']);
        # Управление фатальными ошибками
        register_shutdown_function([__CLASS__, 'fatalErrorHandler']);
        # Управление исключениями
        set_exception_handler([__CLASS__, 'exceptionHandler']);
    }

    /**
     * Управление ошибками
     * @param $errno Код (номер) ошибки
     * @param $errstr Сообщение ошибки
     * @param $errfile Файл ошибки
     * @param $errline Строка в файле ошикбки
     * @return bool Предотвращение дальнейшего выполнения
     */
    public static function errorHandler($errno, $errstr, $errfile, $errline)
    {
        self::show($errno, $errstr, $errfile, $errline);
        # Не передается ошибка далее на обработку
        return true;
    }

    /**
     * Отображение ошибок на экран
     * @param $errno Код (номер) ошибки
     * @param $errstr Сообщение ошибки
     * @param $errfile Файл ошибки
     * @param $errline Строка в файле ошикбки
     */
    private static function show($errno, $errstr, $errfile, $errline)
    {
        http_response_code(self::$status);
        echo "[" . date('Y-m-d H:i:s') . "] <b>" . self::getErrorName($errno) .
            "</b> в файле {$errfile} на строке <b>{$errline}</b>:<br>{$errstr}<br>";
        $message = "[" . date('Y-m-d H:i:s') . "]" . self::getErrorName($errno) .
            " в файле {$errfile} на строке {$errline}:" . PHP_EOL . $errstr . PHP_EOL . PHP_EOL;
        self::writeLog($message);
    }

    /**
     * Получение наименования класса ошибки по ее коду
     * @param $error integer Номер ошибки
     * @return string Наименование класса ошибки
     */
    private static function getErrorName($error)
    {
        $error_name = $error;
        if (array_key_exists($error, self::ERRORS)) {
            $error_name = self::ERRORS[$error];
        }

        return $error_name;
    }


    private static function writeLog($message)
    {
        $errors_config_section = Config::getSettings('logs', 'errors');
        $log_file = File::createFile($errors_config_section['filename'], $errors_config_section['extension'], LOG);
        File::write($log_file, $message);

        header("Location: " . Url::to($errors_config_section['controller'], self::$status));
    }

    /**
     * Управление фатальными ошибками
     * @return bool Предотвращение дальнейшего выполнения
     */
    public static function fatalErrorHandler(int $status = 500)
    {
        self::$status = $status;
        if (!empty($error = error_get_last()) && $error['type'] && (E_ERROR | E_PARSE | E_COMPILE_ERROR | E_CORE_ERROR)) {
            ob_get_clean();
            self::show($error['type'], $error['message'], $error['file'], $error['line']);
        }

        return true;
    }

    /**
     * Управление исключениями
     * @param \Exception|\Error $ex Исключение
     * @return bool Предотвращение дальнейшего выполнения
     */
    public static function exceptionHandler($ex, int $status = 500)
    {
        self::$status = $status;
        self::show(get_class($ex), $ex->getMessage(), $ex->getFile(), $ex->getLine());
        return true;
    }
}
php
  • 2 2 个回答
  • 10 Views

2 个回答

  • Voted
  1. Best Answer
    Ипатьев
    2020-03-18T05:35:58Z2020-03-18T05:35:58Z

    目前尚不清楚重定向与它有什么关系。

    重定向是发生错误时您可以做的最糟糕的事情。

    有诸如 HTTP 返回码之类的东西。这东西非常有用和方便。
    它告诉客户他的请求是如何结束的。
    因此,不应欺骗客户。并且您应该准确给出与页面状态相对应的返回码。
    如果在处理请求后,应该请求另一个 URL,那么我们发送 3xx 代码和 Location: 标头。但是如果请求失败,那么唯一正确的响应代码是 500,没有任何重定向。

    显示错误页面的代码的不同之处仅在于检查负责站点模式的变量 - 战斗或开发中。取决于此,是否显示相似性。返回码保持不变 - 500,没有重定向。

    捕获渲染错误是少数合理的缓冲情况之一。但是不要被缓冲冲昏了头脑——就像任何错误消息一样,不能修改标题信息有助于程序员。并且不应该不必要地堵塞这个错误。也就是说,缓冲应该只在视图中的输出直接开始之前打开。

    • 3
  2. Сергей Коновалов
    2020-03-18T05:13:37Z2020-03-18T05:13:37Z

    您需要使用 ob_start() 缓冲视图的渲染,并且只有在一切正常时才将其输出到流中。在这种情况下,不会发生“已经发送的标头”。

    • 1

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    根据浏览器窗口的大小调整背景图案的大小

    • 2 个回答
  • Marko Smith

    理解for循环的执行逻辑

    • 1 个回答
  • Marko Smith

    复制动态数组时出错(C++)

    • 1 个回答
  • Marko Smith

    Or and If,elif,else 构造[重复]

    • 1 个回答
  • Marko Smith

    如何构建支持 x64 的 APK

    • 1 个回答
  • Marko Smith

    如何使按钮的输入宽度?

    • 2 个回答
  • Marko Smith

    如何显示对象变量的名称?

    • 3 个回答
  • Marko Smith

    如何循环一个函数?

    • 1 个回答
  • Marko Smith

    LOWORD 宏有什么作用?

    • 2 个回答
  • Marko Smith

    从字符串的开头删除直到并包括一个字符

    • 2 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5