为什么我的第一个PHP类不能像预期的那样工作?


Why isn't my first ever PHP class working as expected?

我正在编写我的第一个PHP类,在编写过程中尝试学习OO概念。这段代码的目标是将用户的IP和相关参数记录到数据库中,稍后我可能会将其用作应用临时禁令的基础。(不,让我们不要讨论这个策略的优点——让我们继续讲编码课程吧!)我有:

class banAss {
    public function __construct(mysqli $db){
        $this->db = $db;
        $this->visitip = $_SERVER['REMOTE_ADDR'];
        $this->visitAgent = $_SERVER['HTTP_USER_AGENT'];
        $this->visitDate = time();
    }
    public function addBan(){
        $sql = "Insert into banned (visitIP, visitAgent, visitDate,) values (?, ?, ?)";
        $stmt = mysqli_prepare($this->db, $sql);
        mysqli_stmt_bind_param($stmt, "ssi", $this->visitip, $this->visitAgent, $this->visitDate);
        mysqli_stmt_execute($stmt);
        mysqli_stmt_close($stmt);
    }
}
$banned = new banAss($db);
$banned->addBan();

值得注意的是,我确实有一个使用mysqli打开的有效数据库连接。我一直在玩这个错误信息。目前是:

Warning: mysqli_stmt_bind_param() expects parameter 1 to be mysqli_stmt, boolean given in /home/c9/public_html/admin/login.php on line 16
Warning: mysqli_stmt_execute() expects parameter 1 to be mysqli_stmt, boolean given in /home/c9/public_html/admin/login.php on line 17
Warning: mysqli_stmt_close() expects parameter 1 to be mysqli_stmt, boolean given in /home/c9/public_html/admin/login.php on line 18

我不明白这些信息。他们认为可能是创建变量$stmt的'mysqli_prepare'行搞砸了,但是怎么回事呢?

警告:mysqli_stmt_bind_param()期望参数1为mysqli_stmt,布尔值在…

仔细阅读:它告诉你,你传递了一个布尔值,而函数并不期望它在那里。mysqli_prepare()在遇到错误时返回布尔值FALSE,这就是您试图传递给mpsqli_stmt_bind_param()函数的内容,从而使产生错误和布尔值FALSE,这只是涓滴。

使用mysqli_error()来获得您得到的确切错误,并可能对如何修复该错误有一点了解。

您的查询有语法错误,这意味着所有准备和后续调用都失败:

$sql = "Insert into banned (visitIP, visitAgent, visitDate,) etc...
                                                          ^---dangling comma

永远不要假设DB操作已经成功。您需要检查是否失败,在您的示例中是返回布尔值FALSE:

$stmt = mysqli_prepare(....);
if ($stmt === false) {
       ... oops something blew up
}