当 mysqli->bind_param() 错误处理失败时获取错误信息

Obtaining error message when mysqli->bind_param() fails for graceful error handling

我有以下 PHP 代码:

$inserted = false ;
printf("Record must be inserted.  Old DB ID is %d.\n", $old_db_id) ;
$insertSQL = "INSERT INTO GoogleAuth ("
     .                               "script"
     .                             ", client_id"
     .                             ", client_secret"
     .                             ", refresh_token"
     .                             ", auth_token"
     .                             ", refresh_token_date"
     .                             ", auth_token_date"
     .                             ", client_info_date"
     .                             ", last_used_date"
     .                             ")"
     .            " VALUES(?, ?, ?, ?, ?, ?, ?, ?, NULL) "
                   ;
printf("Preparing statement....\n") ;
$stmt = $mySQL->prepare($insertSQL) ;
if ($stmt) {
    printf("Binding parameters...\n") ;
    if ($stmt->bind_param("sssssiiii"
                        , $page_file
                        , $clientId
                        , $clientSecret
                        , $refreshToken
                        , $authToken
                        , $authTokenDate
                        , $refreshTokenDate
                        , $clientInfoDate
                        , $now
                         )) {
        print("Bind returned true\n") ;
        if ($stmt->execute()) {
            $inserted = true ;
            }
        }
    else {
        printf("Bind failed.  %s\n", $stmt->error) ;
        }
    }
if ($inserted) {
    printf("row inserted.\n") ;
    }
else {
    printf("Insert failed! %s\n", $mySQL->error) ;
    trigger_error("Insert failed.  Dang it!", E_USER_ERROR) ;
    }

当我执行这段代码时,打印如下:

Record must be inserted.  Old DB ID is 0.
Preparing statement....
Binding parameters...
Bind failed.
Insert failed!

注意 $stmt->error 值和 $mySQL->error 值都是空的!

能否请您帮助我了解如何可靠地获取与此类故障相关的错误消息(and/or 错误代码)? (我最终发现我用 9 个变量代替了 8 个替换标记……这不是重点。重点是弄清楚如何从 mysql 中获取实际错误。)

谢谢!

编辑

顺便说一句,我看过像 这样的文章,它们讨论了有趣的变量名重用。这不适用于此处。 $stmt 未在此应用程序的其他任何地方使用。

EDIT2

有人建议这是 this problem. However, the difference is that the goal here is to obtain the failure message so that it can be analyzed for proper handling. (Some errors may be manageable, depending upon circumstances.) In any event, such process makes it possible to GRACEFULLY close down a program, rather than the rude and immediate result that comes from throwing failure errors. As I read the other problem 的副本,目的是确保错误进入日志,并且程序被中止。

失败(类型过多)会产生警告,所以stmt->error returns什么都没有,可以调用error_get_last函数找回。

if(!$stmt->bind_param(....))
{
    $err = error_get_last();
    if($err)
        printf("Bind failed.  %s\n", $err['message']) ;
}

在@shingo 的带领下 - 在接受他的回答后,我做了以下功能,希望能在这方面帮助其他人。

function GetMySqlError($mysql = null, $stmt = null) {
    // MySQL error reporting is inconsistent.  Sometimes failure error
    // message will be in $mysql->error, sometimes in $stmt->error,
    // and sometimes it's necessary to inspect error_get_last().  Sheesh!

    // This routine will inspect all three, and will return the
    // FIRST nonblank value found in:
    //     stmt->error
    //     mysql->error
    //     error_get_last()['message']

    $messageMySql = "" ;
    $messageStmt  = "" ;
    $err          = null;
    $messageLast  = "" ;
    $returnValue  = null ;

    if (is_object($stmt) && property_exists($stmt, "error")) {
        $messageStmt = $stmt->error ;
        }
    if (is_object($mysql) && property_exists($mysql, "error")) {
        $messageMySql = $mysql->error ;
        }
    if ($err = error_get_last()) {
        $messageLast = $err['message'] ;
        }
    if (strlen($messageStmt) > 0) $returnValue = $messageMySql ;
    elseif (strlen($messageMySql) > 0) $returnValue = $messageStmt ;
    elseif (strlen($messageLast) > 0) $returnValue = $messageLast ;
    return $returnValue ;
    }

可以这样称呼:

GetMySqlError($mysql_object) ;
GetMySqlError($myaql_object, $statement_object) ;
GetMySqlError($statement_object) ;

Example:
    printf("MySQL/statement error: %s\n", GetMySqlError($mySql, $stmt)) ;

再次感谢@shingo

注意:我认为没有必要在此处包括连接错误。那是可以做到的,但我已经有了自己的例程。

注意:这可以提高效率。我只为这个答案选择了可读性。