【问题标题】:How to gracefully die?如何优雅地死去?
【发布时间】:2011-03-24 20:51:11
【问题描述】:

所以我刚刚阅读了Why to never use 'or die'.

我比以往任何时候都更加困惑。我正在验证一个复杂的表单,我通过许多嵌套级别的 if 语句和什么不是,我将一个变量传递给称为 $status 的表单,它只能是“新”或“编辑”。然后,当用户提交表单以再次验证时,表单将 $status 值作为隐藏字段 ($_POST) 传递。我想确保用户不会意外更改此设置,因此我想在“新”或“编辑”以外的其他内容通过时捕获错误。 (虽然我想完全消除用户在理想世界中影响这个变量的可能性。)

所以我想我会在 if 语句中使用 DIE()

<nested ifs>
    Select ($status){
        Case 'edit':
            break;
        Case 'new':
            break;
        default:
            //using example from article
            trigger_error("An error that should not occur has occurred", E_USER_ERROR);
            break;
    }
</nested ifs>

我真的不明白这怎么比 die() 更干净?本质上,我想调用另一个函数,该函数向用户显示他们在这个时刻可以做什么来修复错误的一些选项,但我希望代码绝对停止运行,因为我不希望 if 语句进一步向下继续解析任何东西,并在发现“新”或“编辑”以外的内容时生成错误。

我不确定我有多清楚,所以请随时要求我详细说明任何不清楚的地方。 (或者更好的是,隐藏的用户字段可以被黑客入侵吗?如何防止?:P)

【问题讨论】:

    标签: php forms error-handling hidden-field


    【解决方案1】:

    trigger_error() 触发由错误处理程序处理的错误。

    使用trigger_error(),您可以优雅地处理错误,例如:

      set_error_handler('ErrorHandler');
    
      function ErrorHandler($errno, $errmsg, $filename, $linenum, $vars)
      {
        print '<pre style="line-height: 2em;">';
        printf("==> Error in `%s' line %s: %s\n\n", $filename, $linenum, $errmsg);
        debug_print_backtrace();
        print '</pre>';
    
        exit($errno);
      }
    

    这是一个简单的例子,但我们公司的网站显示了一个友好的错误页面,并向我发送了一封电子邮件,说我是个白痴,在某个地方搞砸了:-)

    die()exit() 相比的优势应该很明显:-)

    exit()在需要退出时仍然可以使用。例如,当您生成模板、输出该模板并希望停止代码执行时。或者当您发送 header('Location: ...'); 标头并希望确保执行停止时......只是不要将其用于处理意外情况(即错误)。

    trigger_error() 还可以让您更好地控制。当您希望执行停止但显示通知时,您可以发送E_USER_NOTICE,当您希望执行停止时发送E_USER_ERROR

    此外,您可以编写更复杂的错误处理函数,其中一些 IP 看到错误,而其余的则没有……对开发很有用。

    但要小心过于复杂的错误处理程序,如果错误处理程序内部发生错误会发生什么...?你可能看过《盗梦空间》:)

    【讨论】:

    • trigger_error() 在哪里适合这个?触发错误函数是否调用 set_error_handler 进而调用 ErrorHandler?顺便说一句,我钦佩地看着这段代码:“哦,太闪亮了”:D
    • @Mallow:这正是发生的事情。 set_error_handler 的优点在于您实际上可以为各种(可处理的)错误类型设置多个处理程序。请注意,某些错误无法处理,例如解析错误。
    • 但是 trigger_error 中的字符串会发生什么情况? ErrorHandler() 在哪里获取它的参数?
    • "Magic" :-) PHP 解释器只是用这些参数调用函数。就像$_SESSIONecho,“它只是”......或者可能稍微更好地表述“它在较低级别提供”。
    • 我喜欢学习新东西。这将被非常昂贵地保存。谢谢大家!
    【解决方案2】:

    您链接到的文章解释了为什么您不应该使用or die,如下所示:

    $result = mysql_query($query) or die('A MySQL query occurred: ' . mysql_error());
    

    显然这是一个坏主意,因为它可能会将有关您的 MySQL 结构的敏感信息输出给恶意用户。

    但是,我认为以您使用die 的方式使用它并没有错(我认为本文的作者会同意我的观点),尽管向用户提供选项列表确实会,成为处理此问题的首选方式。

    【讨论】:

    • 啊,我怀疑“或死”是他的主要关注点,但我不想把手放在火里。
    猜你喜欢
    • 2020-07-28
    • 1970-01-01
    • 1970-01-01
    • 2011-03-20
    • 1970-01-01
    • 2017-10-31
    • 2019-07-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多