我在互联网上看到过这个问题,但其他人的解决方案都没有修复我的错误。我有以下PHP代码:
$err = false;
$mysqli = getMysqlConnection();
if ($stmt = $mysqli->prepare("INSERT INTO users (username, email, regtime, emailverified, type) values (?,?,?,?,?);"))
{
date_default_timezone_set("America/New_York");
$dateStr = date("m-d-Y h:i:s");
$emailverified = 0;
$type = 0;
$stmt->bind_param('sssii', $username, $email, $dateStr, $emailverified, $type);
$rc = $stmt->execute();
$err = $rc ? $err : true;
$userId = $stmt->insert_id;
if ($stmt = $mysqli->prepare("INSERT INTO usercreds (user_id, username, hash) VALUES (?,?,?);") && $err === false)
{
//
//right here, for some reason, $stmt is true (boolean), not an object
//
$stmt->bind_param('iss', $userId, $username, $hash);
$rc = $stmt->execute();
$err = $rc ? $err : true;
}
else {
$err = true;
}
}
第一个查询运行时没有问题,但第二个查询在调用bind_params时中断。我得到错误
致命错误:未捕获错误:调用布尔上的成员函数bind_param()
这意味着(我已经确认)第二次执行$stmt = $mysqli->prepare()
时,它返回的是布尔值,而不是对象。此外,它正在回归真实,我觉得这很奇怪。
我已经对我的查询进行了四次检查,它是完全正确和有效的。然而,由于某种原因,当我第二次尝试准备语句时,prepare方法返回的是布尔值,而不是语句对象。
另一个注意事项是,在第二个prepare()不输出任何内容后,回显$mysqli->错误。
如何解决此问题?
思考:
我有一部分感觉是因为我连续两次使用同一个mysqli对象?或者可能是因为我连续两次使用同一语句对象?为了执行第二个查询,是否需要对其中一个对象进行某种"关闭"或"重置"?
另一个编辑:
我的第二个查询有效的额外证据。我复制粘贴了它,并替换了?'s,在mysql工作台中执行,运行非常好。
INSERT INTO usercreds (user_id, username, hash) VALUES (1234567890,'testusr','hashhashhash');
您的问题是由本质上错误的错误处理方式引起的。也就是说,除了产生错误之外,还会使代码膨胀。
以下是您真正需要的唯一代码:
date_default_timezone_set("America/New_York");
// below is the only line you need for the error handling
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = getMysqlConnection();
$dateStr = date("m-d-Y h:i:s");
$emailverified = 0;
$type = 0;
$stmt = $mysqli->prepare("INSERT INTO users (username, email, regtime, emailverified, type) values (?,?,?,?,?)");
$stmt->bind_param('sssii', $username, $email, $dateStr, $emailverified, $type);
$stmt->execute();
$userId = $mysqli->insert_id;
$stmt = $mysqli->prepare("INSERT INTO usercreds (user_id, username, hash) VALUES (?,?,?)");
$stmt->bind_param('iss', $userId, $username, $hash);
$stmt->execute();
剩下的取决于你在出现错误时要做什么。
您正在将$mysqli->prepare(..) && $err === false
的结果分配给$stmt
。这是一个布尔表达式。您想要以下任一变体:
if (($stmt = $mysqli->prepare(...)) && $err === false)
if ($err === false && $stmt = $mysqli->prepare(...))