通过将用户的IP,失败的尝试次数和最后的尝试时间记录到名为的MySQL数据库表中,我有一种简单的登录系统保护机制bannedusers。但是,当我尝试使用以下代码在数据库中插入新条目时,execute()函数将返回false并无法执行。
bannedusers
代码如下:
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 ('?','?','?')";
但是我在这里发现它实际上使查询停止工作(仍然尝试过并在bind_param()上收到错误)。我尝试将类型更改为’sii’或’sss’或’ssi’,这都导致查询失败。我尝试在SQL查询的末尾添加分号,但这没有任何改变。在所有情况下,“查询失败!” 对话框弹出,没有其他错误(除了上面提到的错误之外,我在VALUES字段周围使用了引号。
任何帮助表示赞赏。
更新:
事实证明,$ip在以某种方式null传递给该函数之前,该函数仅在将MySQL错误级别提高到MYSQLI_REPORT_ALL时才会导致错误。
$ip
null
要么将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语法显然只需要在 字符串 两边加上引号。