【问题标题】:PHP PDO error handling halting executionPHP PDO 错误处理停止执行
【发布时间】:2015-06-01 00:25:17
【问题描述】:

我是来自 ASP 的 PHP 新手,我很难理解错误处理是如何与 PHP 和 PDO 一起工作的。这就是我正在做的事情......

PDO 设置为:

PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION

我正在对 PHP 页面进行 AJAX 调用以处理一些数据并使用 PDO 将其保存到 MySQL。我在 try catch 中有我的数据库脚本,如下所示:

function processStuff(){
    try {
       $sth = $db->prepare( query );
       $sth->execute();
    } catch (PDOEXCEPTION $e){
        //log error
    }

    //if no error
    return array(some json);
}

假设发生了不好的事情,我收到如下错误:

Error: exception 'PDOException' with message 'SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'field' cannot be null' in C:\filepath:202

发生的情况是错误正在停止脚本,从而导致调用页面挂起。 AJAX 正在等待一个 JSON 响应,该响应将告诉它是成功还是失败。但是因为挂起,所以没有得到响应,所以我没有机会向用户展示有错误。

我还有一个自定义错误处理函数:

function errorHandler($errno, $errstr, $errfile, $errline) {
    //log errors
}

set_error_handler("errorHandler")

可以记录错误。但是,由于我是新手,我不确定如何在 try/catch 中使用它。

所以我的问题是,当发生 PDO 异常时如何记录错误并确保脚本继续处理,以便使用 AJAX 的调用页面不会挂起。

围绕类似问题的所有其他答案都假设我似乎还没有知识水平。我不清楚我是否应该抛出要捕获的错误,或者它是否会自动被抛出。如果 PDO 自动抛出它,我如何在 catch 中调用我的错误处理程序?我会用吗:

errorHandler();

如果我切换到 ERRMODE_SILENT,我相信它会继续处理,我如何检测错误以便将其抛出?

我确信有一些基本概念我只是不了解它是如何工作的。代码很棒,但任何解释都非常感谢。

谢谢。

更新: 这是实际的 try 块:

        try {
            $sth = $dbh->prepare ("INSERT INTO email_validation (email, val_code) VALUES (:a1, :a2)");
            $sth->bindParam (":a1", $email);
            $sth->bindParam (":a2", $gencode);
            $sth->execute ();
        } catch (PDOEXCEPTION $e) {
            $err = true;
            $errmsg = date("F j, Y, g:i a") . "\n" . ERR_URL . "\n" . $e . "\n\n";
            error_log($errmsg,3,ERR_LOG_PATH_INT);
        }

AJAX 看起来像这样:

    $.post('Functions/AJAX-new-account.php', $('form').serialize(), function(data) {
        var c = data.check;
        if(c==1){
            //process client side stuff here
        }else{
            //----Ooops there was an error-----//
            //show error to client
        };
        return false;
    },"json");

我猜 JSON 正在被写入,但我不明白为什么我没有在我的 AJAX 中访问 }else{ 并且页面似乎停滞不前。

另一个更新:所以我刚刚尝试过

trigger_error("blah blah");

在 catch 块中,它停止挂起。 errorHandler 似乎已经正确处理了错误,虽然我的 AJAX 处理不正确,但它确实停止了挂起。这是处理这个问题的正确方法,还是有更好的方法?

【问题讨论】:

  • 处理应该继续正常,因为您已经捕获了异常。你能显示实际的代码,包括catch 块中的内容吗?
  • 所以你在调用一个AJAX页面,而这个错误是在ajax页面中发生的?您的问题是 AJAX 响应没有发回错误消息?在您的 catch 中放置一个包含错误消息的返回值,然后使用 jquery ajax 调用“捕获”它。如果 json 是失败事件,则显示消息。
  • 一个 AJAX (XHR) 响应肯定 正在发送,即使没有 HTTP 200 状态代码(如果没有,则意味着 PHP 进程/代码永远不会终止并且 HTTP 通道永远不会关闭,这是值得怀疑的!)。这可以通过查看浏览器工具的“网络”选项卡简单验证。确保在 JavaScript/jQuery/XHR 中处理 failing 情况(用于“错误 JSON”和/或非 200 响应)。
  • 发生错误时我收到 200 响应。我不确定如何处理失败的情况。

标签: php ajax pdo error-handling


【解决方案1】:

这里有几个问题,我会尽力一一解答。

如果我切换到 ERRMODE_SILENT,我相信它会继续处理,我如何检测错误以便将其丢弃?

在这种情况下,您需要使用 if 语句检查 PDO 错误代码,而不是使用 try/catch,例如if ($db->errorCode() !== null)(请参阅 PHPDoc 了解 PDO Error Handling)您将在其中记录错误,也许将 HTTP Response Code 设置为您对 Javascript 的期望。

为什么我的 AJAX 请求在此失败后挂起?

我怀疑您的页面实际上并未挂起;相反,由于某种原因,没有 JS 被执行。在您的第一次尝试中,您将收到 500 错误代码,这不会触发您提供给 $.post.success() 函数。为了在这种情况下查看问题,您需要在 AJAX 请求中添加 .fail() 回调。

一旦您切换到使用trigger_error,将返回 200 OK,因为没有引发异常。我不确定您所说的“我的 AJAX 处理不正确”是什么意思。

这是处理这个问题的正确方法,还是有更好的方法?

这在很大程度上取决于偏好。 PDO 异常对我来说应该是非常罕见的,因为我在将数据发送到数据库之前正在处理和验证数据。在您的情况下,Column 'field' cannot be null 是您应该事先检查的一个很好的例子。

如果确实发生了 PDO 异常,我会尝试优雅地处理它——这意味着 catching 它,记录错误,将 HTTP 响应代码设置为合理的值(可能 400 Bad Request 会这样做),然后返回带有错误消息的结果。在 Javascript 中,我有一个 .fail 方法来解析错误结果并显示适合用户的内容。为成功和失败案例提供完全独立的方法是一个很好的设计原则,可以帮助您避免代码混乱。

我希望这可以帮助您走上正确的道路。

【讨论】:

  • 感谢 xanthien,这给了我一个很好的起点。一个问题......所以使用 SILENT 案例,我会一起摆脱 try/catch 并执行类似的操作: if($db->e​​rrorCode() !== null){trigger_error();} 为了记录错误?
  • 没错。它看起来像“if ($sth->errorCode() !== null) { trigger_error('来自 PDO 的意外异常!消息:' .print_r($sth->errorInfo()), E_USER_ERROR); }”虽然我可能更愿意将它保留在 ERRMODE_EXCEPTION 上,因为异常带有一个方便的 '$ex->getMessage()',它已经有一个格式很好的错误消息,并且 try/catch 比错误条件更明确if() 语句。
  • 非常感谢您的帮助。我认为这肯定会让我到达我需要去的地方。
猜你喜欢
  • 2015-08-28
  • 2015-07-15
  • 2010-12-20
  • 2012-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-14
  • 1970-01-01
相关资源
最近更新 更多