【问题标题】:mysqli_stmt::execute() returning false and statement not executing [duplicate]mysqli_stmt::execute() 返回 false 且语句未执行
【发布时间】:2013-08-16 21:28:40
【问题描述】:

我有一个简单的登录系统保护机制,将用户的IP、失败尝试次数和最后一次尝试时间记录到名为bannedusers 的MySQL 数据库表中。但是,当我尝试使用下面的代码将新条目插入数据库时​​,execute() 函数返回 false 并且无法执行。

代码如下:

private $con;

function updateTable($IP, $attempt, $exists){
    $time = time();

    //The following statement is actually in the constructor, moved here for completeness
    $this->con = new mysqli(DB_SERVER, DB_USER, DB_PASSWORD, DB_NAME); //All these constants are predefined and verified to be correct.

    if($this->con->connect_error){
        return true; //If there is a connection error, just let the user log in... We'll deal with this later
    }

    //Another function already determines if the entry exists or not.
    if(!$exists){
        //ip, retrycount, attempttime are the name of the fields. IP is a 40-char wide VARHCAR, retrycount is a tinyint and attempttime is a big int.
        $query = "INSERT INTO bannedusers (ip, retrycount, attempttime) VALUES (?,?,?)";

        if($stmt = $this->con->prepare($query)){

            //This following statement executes without throwing errors and returns true.
            $stmt->bind_param('sii', $IP, $attempt, $time);

            $successful = $stmt->execute();
            $stmt->close();

            if(!$successful){
                //Causes a small dialog to appear telling you the query failed.
                echo "<script type='text/javascript'>alert('Failed query!');</script>";
            }
        }
    }else{
        //Unrelated code omitted.
    }
}

我对 php 和 MySQL 比较陌生,通过研究我发现 SQL 语法显然需要在查询的 VALUE 部分的字段周围加上引号,例如:

$query = "INSERT INTO bannedusers (ip, retrycount, attempttime) VALUES ('?','?','?')";

但我发现here 实际上停止了查询的工作(仍然尝试过,但在 bind_param() 上出现错误)。我尝试将类型更改为“sii”或“sss”或“ssi”,所有这些都导致查询失败。我尝试在 SQL 查询的末尾添加一个分号,但这并没有改变。在所有情况下,“查询失败!”弹出对话框,没有其他错误(除了上面提到的那个我在 VALUES 字段周围使用引号。

感谢任何帮助。

更新:

原来$ip 在传递给函数之前不知何故是null

【问题讨论】:

    标签: php mysql sql mysqli


    【解决方案1】:

    将mysqli设置为异常模式

    mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
    

    或者总是检查每个mysqli操作的结果并手动抛出mysqli错误:

    $result = $stmt->execute();
    if (!$result) {
        throw new Exception($mysqli->error);
    }
    

    这是了解您的 execute() 出了什么问题的唯一方法;

    我发现 SQL 语法显然需要在 VALUE 的字段周围加上引号

    当然是错的。 SQL 语法显然只需要在 strings 周围加上引号。

    【讨论】:

    • mysqli_report(MYSQLI_REPORT_STRICT); 将启用异常,因此您不必自己抛出它们。 source
    • 使用函数 mysqli_report(MYSQLI_REPORT_STRICT),没有错误。检查 $this->con->error 的返回值,它是空白的。使用phpmyAdmin检查数据库,没有添加记录。
    • @CPUTerminator 仔细检查它。从未见过函数返回错误但 con->error 为空的情况。你如何检查它?你还能看到其他错误吗?
    • 原来 php 用字符串引用搞砸了我,导致 $ip 变为空(在它被传递到这个函数之前)。事实证明 mysqli_report(MYSQLI_REPORT_STRICT) != mysqli_report(MYSQLI_REPORT_ALL) 其中 MYSQLI_REPORT_ALL 实际上会引发异常,而 MYSQLI_REPORT_STRICT 不会。虽然 mysqli 对象没有错误,但操作本身确实引发了异常,因为 $ip 为空且字段不能为空。感谢您向我展示 mysqli_report();功能,以前从未听说过。
    • 我相信Exception() 应该是Exception($result-&gt;error);Exception($stmt-&gt;error); 而不是Exception($mysqli-&gt;error); 我说的对吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-19
    • 2012-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多