mysqli_stmt::execute() 返回 false 并且语句未执行

ini*_*mfs 3 php mysql sql mysqli

我有一个简单的登录系统保护机制,通过将用户的 IP、失败的尝试次数和上次尝试时间记录到名为bannedusers. 但是,当我尝试使用下面的代码将新条目插入数据库时​​,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.
    }
}
Run Code Online (Sandbox Code Playgroud)

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

$query = "INSERT INTO bannedusers (ip, retrycount, attempttime) VALUES ('?','?','?')";
Run Code Online (Sandbox Code Playgroud)

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

任何帮助表示赞赏。

更新:

事实证明,这$ipnull在传递到函数之前以某种方式发生的,如果 MySQL 错误级别提升到 MYSQLI_REPORT_ALL,只会导致错误。

You*_*nse 5

要么将 mysqli 设置为异常模式

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
Run Code Online (Sandbox Code Playgroud)

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

$result = $stmt->execute();
if (!$result) {
    throw new Exception($mysqli->error);
}
Run Code Online (Sandbox Code Playgroud)

这是知道你的 execute() 有什么问题的唯一方法;

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

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