【问题标题】:How to automatically stop any script and redirect to an error page if an error/warning/notice is uncaught如果未捕获错误/警告/通知,如何自动停止任何脚本并重定向到错误页面
【发布时间】:2013-06-13 08:22:25
【问题描述】:

编辑:关于上面的链接答案,它相似但不同,因为我的目标是在错误页面中调试错误。


有时意外错误很难调试,因为错误报告打印在奇怪的 HTML 元素中,例如隐藏的 div 或选项元素。

如果触发了任何未捕获的错误,是否没有办法自动将错误对象存储在全局变量中并将脚本重定向到错误页面?有没有办法对所有错误执行此操作,包括通常不会退出脚本的错误,如警告和通知?

【问题讨论】:

标签: php debugging error-handling


【解决方案1】:

您可以使用custom error handler 执行此操作。将错误转化为异常是一种好方法,可以让您对错误处理进行非常精细的控制:

set_error_handler(function ($errno, $errstr, $errfile, $errline) {
    throw new ErrorException($errstr, $errno, 0, $errfile, $errline);
});

您可以决定对哪些错误抛出异常以及忽略哪些错误;例如,您可能想忽略或只记录 E_NOTICE。使用全局 try..catch 块或 custom exception handler,您现在可以非常轻松地决定在出现错误时该怎么做。

【讨论】:

  • ... 您还应该了解 ob_* 函数集:php.net/manual/en/ref.outcontrol.php。缓冲您的站点输出并仅在没有发生错误时刷新它,如果发生错误,只需显示错误页面并丢弃原始站点输出
  • @hek2mgl:我不知道我是否可以封装你的建议。我想在网站投入生产时轻松关闭此功能。
  • 我在没有完全重写错误处理程序的情况下解决了它,请参阅我的答案:)
【解决方案2】:

确实有一些方法可以将错误重定向到页面、记录它们、跟踪它们等等。 PHP 相当灵活。好消息是您不必自行编写此类方法,框架可用于此,但您也可以在没有这些方法的情况下生存,因为 PHP 的内置错误处理工具足够可用。如果配置正确,PHP 将中止错误(或警告,由您决定),记录它们,如果插入 Web 服务器,甚至返回 HTTP 500 服务器错误代码。

您可能需要正确配置 PHP。它完全有能力提供更好的错误处理工作流程。首先,禁用错误打印,这不是表现良好的应用程序应该报告错误的方式,而且在最坏的情况下,会帮助恶意用户使用打印的错误输出闯入您的系统。你不是唯一一个查看你的网页的人,你知道,并不是所有的用户看到这些都会感到困惑,有些人会等待这些。这是您可以使用的指令之一,编辑配置 PHP 的“php.ini”文件;作为内容生成的一部分,它会禁止将错误输出与任何其他 PHP 输出混合:

display_errors = "0"

您也可以将其设置为“stderr”,这在使用命令行 PHP 调用调试脚本时是一件好事,因为输出将被发送到另一个文件通道,即所谓的标准错误。

现在注意以下“php.ini”指令:

log_errors = "1"

根据调用 PHP 的方式,以上将有 PHP 记录错误到文件或使用 Web 服务器错误记录工具。例如,在 UNIX 系统上,列出错误及其详细信息的日志文件将驻留在“/var/log/www/”中。

仔细阅读有关错误处理和报告的 PHP 文档,可能从以下页面开始:

http://www.php.net/manual/en/book.errorfunc.php

不要忘记阅读安装配置。我再重复一遍,公共 PHP 脚本永远不会出现 PHP 显示错误!(是的,我知道您正在调试,但这些天我不能再强调这一点了)。 p>

【讨论】:

  • 我更喜欢在开发过程中显示错误,因为它调试起来更快。当网站投入生产时,我会记录错误。
  • 为什么不呢,@Lucas。但是,我发现在开发过程中显示错误可能会干扰调试本身,因为错误输出可能会蔓延到不可见的元素中。此外,警告和其他重要信息可能会出现在您决定发布之前不会费心查看的日志文件中。 500 个服务器错误代码也是如此 - 您的脚本将生成输出,但 PHP 可能会更改响应错误代码,如果这些代码提供给例如 Adob​​e Flash Player 客户端或 Web 服务消费者,这可能会破坏您的页面。
【解决方案3】:

感谢@MladenB。和deceze,我解决了我的问题。这就是我编写解决方案的方式:

在 config.php 文件中,包含在您的脚本中(最好将函数移动到个人库文件中):

<?php

function my_error_handler($errno, $errstr, $errfile, $errline)
{
    throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
}

function my_exception_handler($e)
{
    /**
     *  Exception handler that pass the error object to an error page.
     *  This is to avoid bad displaying or hiding of error reports.
     *  
     *  @param $e Exception  The exception to manage
     */

    if (session_status() !== PHP_SESSION_ACTIVE)
    {
        session_start();
    }

    session_register_shutdown();

    $_SESSION['error'] = $e;

    header('Location: error.php');
    exit();
}

set_error_handler('my_error_handler');
set_exception_handler('my_exception_handler');

在error.php中:

<?php

session_start();
session_register_shutdown();

$e = $_SESSION['error'];

echo '<h2>Stack trace</h2>';
echo var_dump($e->getTrace());

throw $e;

【讨论】:

    猜你喜欢
    • 2012-01-29
    • 1970-01-01
    • 1970-01-01
    • 2021-11-02
    • 2010-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-21
    相关资源
    最近更新 更多