怎么检查没有。使用MYSQLI_STMT_PREPARE和MYSQLI_FETCH_ARRAY时返回的行数?

时间:2015-02-01 02:14:37

标签: php mysqli

我以为我可以使用MYSQLI_STMT_NUM_ROWSMYSQLI_STMT_STORE_RESULT来检查否。返回的行数。 (参见注释行/// 1 ///,/// 2 ///,/// 3 ///)

但在下面的上下文中似乎没有。

此代码确实有效(没有注释行),但我尝试添加额外的检查,以确认返回的记录不超过1条。 (尽管情况总是如此,因为表格中的电子邮件字段是唯一的,但无论如何都不会受到影响)。

有人能说清楚我做错了吗?

这是我得到的错误(如果WHILE ...行,则为第86行):

  

第86行的脚本'L:\ includes \ login_functions.inc.php'发生错误:mysqli_fetch_array()要求参数1为mysqli_result,给定布尔值

注:

这是原始代码的精简版。

$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);
?>

2 个答案:

答案 0 :(得分:2)

调用mysqli_stmt_store_result()后,MySQL驱动程序将不允许您对结果集进行操作,直到获取所有行或释放结果集并关闭语句。因此,对mysqli_stmt_get_result()的后续调用将返回false,并可能导致错误,如

  

命令不同步;你现在不能运行这个命令

您可以使用echo mysqli_error($dbc);

查看

使用mysqli_stmt_get_result()传输语句的结果集将允许您访问其num_rows属性,因此您实际上不需要使用mysqli_stmt_store_result()。相反,在检查返回的行数之前,只需依赖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);
}

答案 1 :(得分:0)

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";
}