Reputation: 1615
I'm pretty new to php coding and managed to resolve a lot of problems myself, but there is 1 I can't get my head around.
$prep_stmt = "SELECT id FROM members WHERE Email = ? LIMIT 1";
$stmt = $mysqli->prepare($prep_stmt);
// check existing Email
if ($stmt) {
$stmt->bind_param('s', $Email);
$stmt->execute();
$stmt->store_result();
if ($stmt->num_rows == 1) {
// A user with this Email address already exists
$error_msg .= '<p class="error">A user with this Email address already exists.</p>';
$stmt->close();
}
$stmt->close();
} else {
$error_msg .= '<p class="error">Database error Line 39</p>';
$stmt->close();
}
My guess is that the code can't get to the 2nd $stmt->close();
in the above code (the one after the if inside the if).
How can I resolve this problem? Is that $stmt->close();
really needed?
Upvotes: 1
Views: 5402
Reputation: 33286
Just remove the if
statements and the close()
method calls. Why have you added that to your code?
Th reason why you are getting this error is because you try to close a statement when its creation failed. You can't close an object which was never created. If prepare()
call fails and you have your error reporting silenced this function will return false
instead of an object.
If you enable proper error reporting there should be no if
statements. See How to get the error message in MySQLi?
Here is how your code should look like:
$prep_stmt = "SELECT id FROM members WHERE Email = ? LIMIT 1";
$stmt = $mysqli->prepare($prep_stmt);
// check existing Email
$stmt->bind_param('s', $Email);
$stmt->execute();
$result = $stmt->get_result();
if ($result->fetch_assoc()) {
// A user with this Email address already exists
$error_msg .= '<p class="error">A user with this Email address already exists.</p>';
}
Try to avoid store_result()
as much as possible. When you enable error reporting then there's no reason for any if
statements. Otherwise, you would need to wrap each line in such statement, because any of these calls could fail: prepare()
, bind_param()
, execute()
, ...
There's no need to close the statement if you fetch all the results. When you call get_result()
you fetch everything from MySQL.
Keep it simple and don't add unnecessary code.
Upvotes: 0
Reputation: 147
You should put store_result()
after execute like bellow:
$stmt->execute();
$stmt->store_result();
if you make a method and pass query, it doesn't work
Upvotes: -1
Reputation: 3434
Why you don't just remove the first one (in the second if statement)? Also remove the close()
in your else
statement because you checked if $stmt
is a legal object. Basically what you say is: $stmt
isn't a legal object, close it. But close what?
This will work in both situations:
$prep_stmt = "SELECT id FROM members WHERE Email = ? LIMIT 1";
$stmt = $mysqli->prepare($prep_stmt);
// check existing Email
if ($stmt) {
$stmt->bind_param('s', $Email);
$stmt->execute();
$stmt->store_result();
if ($stmt->num_rows == 1) {
// A user with this Email address already exists
$error_msg .= '<p class="error">A user with this Email address already exists.</p>';
//Remove this one: $stmt->close();
}
$stmt->close();
} else {
$error_msg .= '<p class="error">Database error Line 39</p>';
//This one can be removed because $stmt isn't a legal object: $stmt->close();
}
Upvotes: 4