如何查号使用 MYSQLI_STMT_PREPARE 和 MYSQLI_FETCH_ARRAY 时返回的行数?
How to check no. of rows returned when using MYSQLI_STMT_PREPARE and MYSQLI_FETCH_ARRAY?
我想我可以使用 MYSQLI_STMT_NUM_ROWS
和 MYSQLI_STMT_STORE_RESULT
来检查是否。返回的行数。 (参见注释行 ///1///、///2///、///3///)
但在下面的上下文中似乎没有。
这段代码确实有效(没有注释行),但我试图添加一个额外的检查,以确认返回的记录不超过 1 条。 (尽管这种情况应该总是如此,因为 table 中的电子邮件字段是唯一的,但无论如何进行检查也无妨)。
任何人都可以阐明我做错了什么吗?
这是我在下面得到的错误(第 86 行,如果 WHILE
... 行):
An error occurred in script 'L:\includes\login_functions.inc.php' on line 86: mysqli_fetch_array() expects parameter 1 to be mysqli_result, boolean given
注意:
这是原始代码的精简版。
$form_email
和 $form_pass
源自表单输入。
代码是程序化的,因为我喜欢这样。
<?php
// Prepared statement.
$prep_sel = 'SELECT user_id, first_name, user_level, pass FROM users WHERE email=? and active is null';
// Initialise connection.
$stmt_sel = mysqli_stmt_init($dbc);
// Check if there are any DB connection problems.
....
// Prepare statement, bind parameters (an integer and a string) and execute the statement
if (mysqli_stmt_prepare($stmt_sel, $prep_sel)) {
mysqli_stmt_bind_param($stmt_sel, 's', $form_email);
mysqli_stmt_execute($stmt_sel);
///1///mysqli_stmt_store_result($stmt_sel);
}
///2///if (mysqli_stmt_num_rows($stmt_sel) == 1) { // one record found.
// Get the results.
$result = mysqli_stmt_get_result($stmt_sel);
while ($row = mysqli_fetch_array($result, MYSQLI_ASSOC)) {
// Now check if the passwords match.
if (password_verify($form_pass, $row['pass'])) {
return array(true, $row);
} else {
$errors[] = 'the details you provided does not match our records';
$errors[] = 'your account has not been activated';
}
}
///3///}
/* close statement */
mysqli_stmt_close($stmt_sel);
?>
调用 mysqli_stmt_store_result()
后,MySQL 驱动程序将不允许您对结果集进行操作,直到获取所有行或释放结果集并关闭语句。因此,随后对 mysqli_stmt_get_result()
的调用将 return false
,并且可能会导致类似
的错误
Commands out of sync; you can't run this command now
您可以通过 echo mysqli_error($dbc);
查看
使用 mysqli_stmt_get_result()
传输语句的结果集将使您可以访问其 num_rows
属性,因此您实际上不需要使用 mysqli_stmt_store_result()
。在检查行数 returned:
之前,只需依赖 mysqli_stmt_get_result()
if (mysqli_stmt_prepare($stmt_sel, $prep_sel)) {
mysqli_stmt_bind_param($stmt_sel, 's', $form_email);
mysqli_stmt_execute($stmt_sel);
// Transfer the result set here:
$result = mysqli_stmt_get_result($stmt_sel);
// Then check rows returned on the $result obj
// using mysqli_num_rows(), not mysqli_stmt_num_rows()
if (mysqli_num_rows($result) == 1) {
while ($row = mysqli_fetch_array($result, MYSQLI_ASSOC)) {
// Check your password, etc....
}
}
else {
// More than 1, do whatever you need to handle this
}
// Close it
mysqli_stmt_close($stmt_sel);
}
function authenticateUser($email, $password){
$stmt = $db->prepare("SELECT user_id, first_name, user_level, pass FROM users WHERE email=? and active is null");
$stmt->bind_param('s', $email);
$stmt->execute();
$res = $stmt->get_result();
if($res->num_rows > 0){
$hash = $res->fetch_object()->pass;
if(password_verify($password, $hash)){
return true;
}
}
return false;
}
调用函数
if(authenticateUser($_POST['email'], $_POST['password'])){
//do something
}
else{
echo "Invalid Email/Password";
}
我想我可以使用 MYSQLI_STMT_NUM_ROWS
和 MYSQLI_STMT_STORE_RESULT
来检查是否。返回的行数。 (参见注释行 ///1///、///2///、///3///)
但在下面的上下文中似乎没有。
这段代码确实有效(没有注释行),但我试图添加一个额外的检查,以确认返回的记录不超过 1 条。 (尽管这种情况应该总是如此,因为 table 中的电子邮件字段是唯一的,但无论如何进行检查也无妨)。
任何人都可以阐明我做错了什么吗?
这是我在下面得到的错误(第 86 行,如果 WHILE
... 行):
An error occurred in script 'L:\includes\login_functions.inc.php' on line 86: mysqli_fetch_array() expects parameter 1 to be mysqli_result, boolean given
注意:
这是原始代码的精简版。
$form_email
和 $form_pass
源自表单输入。
代码是程序化的,因为我喜欢这样。
<?php
// Prepared statement.
$prep_sel = 'SELECT user_id, first_name, user_level, pass FROM users WHERE email=? and active is null';
// Initialise connection.
$stmt_sel = mysqli_stmt_init($dbc);
// Check if there are any DB connection problems.
....
// Prepare statement, bind parameters (an integer and a string) and execute the statement
if (mysqli_stmt_prepare($stmt_sel, $prep_sel)) {
mysqli_stmt_bind_param($stmt_sel, 's', $form_email);
mysqli_stmt_execute($stmt_sel);
///1///mysqli_stmt_store_result($stmt_sel);
}
///2///if (mysqli_stmt_num_rows($stmt_sel) == 1) { // one record found.
// Get the results.
$result = mysqli_stmt_get_result($stmt_sel);
while ($row = mysqli_fetch_array($result, MYSQLI_ASSOC)) {
// Now check if the passwords match.
if (password_verify($form_pass, $row['pass'])) {
return array(true, $row);
} else {
$errors[] = 'the details you provided does not match our records';
$errors[] = 'your account has not been activated';
}
}
///3///}
/* close statement */
mysqli_stmt_close($stmt_sel);
?>
调用 mysqli_stmt_store_result()
后,MySQL 驱动程序将不允许您对结果集进行操作,直到获取所有行或释放结果集并关闭语句。因此,随后对 mysqli_stmt_get_result()
的调用将 return false
,并且可能会导致类似
Commands out of sync; you can't run this command now
您可以通过 echo mysqli_error($dbc);
使用 mysqli_stmt_get_result()
传输语句的结果集将使您可以访问其 num_rows
属性,因此您实际上不需要使用 mysqli_stmt_store_result()
。在检查行数 returned:
mysqli_stmt_get_result()
if (mysqli_stmt_prepare($stmt_sel, $prep_sel)) {
mysqli_stmt_bind_param($stmt_sel, 's', $form_email);
mysqli_stmt_execute($stmt_sel);
// Transfer the result set here:
$result = mysqli_stmt_get_result($stmt_sel);
// Then check rows returned on the $result obj
// using mysqli_num_rows(), not mysqli_stmt_num_rows()
if (mysqli_num_rows($result) == 1) {
while ($row = mysqli_fetch_array($result, MYSQLI_ASSOC)) {
// Check your password, etc....
}
}
else {
// More than 1, do whatever you need to handle this
}
// Close it
mysqli_stmt_close($stmt_sel);
}
function authenticateUser($email, $password){
$stmt = $db->prepare("SELECT user_id, first_name, user_level, pass FROM users WHERE email=? and active is null");
$stmt->bind_param('s', $email);
$stmt->execute();
$res = $stmt->get_result();
if($res->num_rows > 0){
$hash = $res->fetch_object()->pass;
if(password_verify($password, $hash)){
return true;
}
}
return false;
}
调用函数
if(authenticateUser($_POST['email'], $_POST['password'])){
//do something
}
else{
echo "Invalid Email/Password";
}