【问题标题】:MySQLi failing to prepare a statementMySQLi 未能准备语句
【发布时间】:2012-02-02 11:55:26
【问题描述】:

我在脚本room.php 中运行两个查询。两者都使用 MySQLi 的prepared statements,代码如下:

/* Get room name */
$stmt = $mysqli->prepare('SELECT name FROM `rooms` WHERE r_id=?');
$stmt->bind_param('i', $roomID);
$stmt->execute();
$stmt->bind_result($roomName)

/* Add this user to the room */
$stmt = $mysqli->prepare('INSERT INTO `room_users` (r_id, u_id) VALUES (?, ?)');
$stmt->bind_param('ii', $roomID, $_SESSION['userID']);
$stmt->execute();

当我运行脚本时,我得到了这个错误:

Fatal error: Call to a member function bind_param() on a non-object in C:\wamp\www\room.php on line 24

这是第二个查询。如果我从脚本中删除第一个查询,一切运行正常。同样,如果我删除第二个查询。这让我相信存在问题,因为我正在重用 $stmt 对象。如果我使用 $stmt2 尝试第二个查询,我仍然会收到错误消息。

我所有的数据库表和字段都存在,所以查询没有问题。

【问题讨论】:

    标签: php mysql pdo mysqli


    【解决方案1】:

    所有 mysqli 函数/方法都可能失败,在这种情况下它们将返回 false。 IE。如果 prepare() 失败 $stmt 不是一个对象,你可以调用一个方法,而是一个 bool(false)。您必须检查返回值并添加一些错误处理,例如

    $stmt = $mysqli->prepare('SELECT name FROM `rooms` WHERE r_id=?');
    if ( !$stmt ) {
        printf('errno: %d, error: %s', $mysqli->errno, $mysqli->error);
        die;
    }
    
    $b = $stmt->bind_param('i', $roomID);
    if ( !$b ) {
        printf('errno: %d, error: %s', $stmt->errno, $stmt->error);
    }
    
    $b = $stmt->execute();
    if ( !$b ) {
      and so on and on
    

    http://docs.php.net/mysqli-stmt.errno 等人


    在这种情况下,您可能会遇到无法创建其他语句的问题,而前一条语句仍有待处理的结果/结果集。
    http://docs.php.net/mysqli-stmt.close:

    关闭准备好的语句。 mysqli_stmt_close() 也释放语句句柄。如果当前语句有待处理或未读结果,此函数将取消它们以便执行下一个查询。

    【讨论】:

    • @Bill :您完全正确,不知道您的编辑请求为何被拒绝....
    • 第二部分对我来说很关键。 $mysqli->prepare 返回 false 但 $mysqli->error 为空;在前面的语句中添加$stmt->close 修复了这个问题。
    猜你喜欢
    • 1970-01-01
    • 2012-12-01
    • 2013-10-22
    • 1970-01-01
    • 2015-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多