mysqli prepare()返回一个布尔值true而不是一个语句对象
I've seen this issue all over the internet but none of the solutions for others have fixed my errors. I have the following PHP code:
$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;
}
}
The first query runs without problems, but the second query breaks on the call to bind_params. I get the error
Fatal error: Uncaught Error: Call to a member function bind_param() on boolean
This means (and I have confirmed) that the second time I do $stmt = $mysqli->prepare()
, it's returning a boolean rather than an object. Furthermore, it's returning true, which I find very strange.
I have quadruple checked my query, and it is perfectly fine and valid. Yet for some reason the second time I try to prepare a statement he prepare method returns a boolean instead of a statement object.
Another note, echoing out $mysqli->error after the second prepare() outputs nothing.
How do I resolve this issue?
Afterthought:
Part of me feels like this is because I'm using the same mysqli object twice in a row? or maybe because I'm using the same statement object twice in a row? Is there some sort of "shutting down" or "resetting" of one of these objects that needs to take place in order to execute a second query?
Another edit:
Additional proof that my second query is valid. I copied and pasted it and replaced the ?'s with values, executed it in mysql workbench, and it ran perfectly fine.
INSERT INTO usercreds (user_id, username, hash) VALUES (1234567890,'testusr','hashhashhash');
Your problem is caused by essentially wrong way of error handling. That is, beside producing errors, is making your code bloat.
Below is the only code you really need:
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();
The rest is depends on what you going to do in case of error.
You are assigning the result of $mysqli->prepare(..) && $err === false
to $stmt
. That is a boolean expression. You want either of these variations:
if (($stmt = $mysqli->prepare(...)) && $err === false)
if ($err === false && $stmt = $mysqli->prepare(...))