【问题标题】:mysqli_stmt_num_rows($stmt) always returns 0? [duplicate]mysqli_stmt_num_rows($stmt) 总是返回 0? [复制]
【发布时间】:2013-12-03 18:28:01
【问题描述】:

我正在为我的 Web 应用程序创建一个登录脚本,并尝试使用 $count = mysqli_stmt_num_rows($stmt); 来查找从 sql select 语句返回的行数,这样我就可以决定是否应该启动会话。

问题是,$count 始终为 0,即使我输入了与数据库中的数据匹配的有效用户名和密码。我已经测试了 select 语句,它工作正常。没有给出错误、语法、SQL 或其他信息,所以我有点不知道发生了什么。

代码:

<?php

    $link = mysqli_connect("localhost", "****", "****", "****");

    //check connection
    if (mysqli_connect_errno()) {
        printf("Connect failed: %s\n", mysqli_connect_error());
        exit();
    }

    // username and password sent from form 
    $myusername=$_POST['myusername'];   
    $mypassword=$_POST['mypassword']; 

// Move to MySQL(i) as MySQL is now obslete and use Prepare statment for protecting against SQL Injection in better and easier way
    $stmt = mysqli_prepare($link, 'SELECT username, password FROM `users` WHERE  `username` =  ? AND  `password` =  ?');

    /* bind parameters for markers */
    mysqli_stmt_bind_param($stmt, "ss", $myusername, $mypassword);

    /* execute query */
    mysqli_stmt_execute($stmt);

    /*count number of rows returned*/
    $count = mysqli_stmt_num_rows($stmt);

    /*display number of rows returned*/
    //echo $count;

    /* bind result variables */
    mysqli_stmt_bind_result($stmt, $myusername, $mypassword);

    /* fetch value */
    mysqli_stmt_fetch($stmt);

    /* close statement */
    mysqli_stmt_close($stmt);

    if($count == 1) {

        session_start();
        $_SESSION['userid'] = $myusername;
        header("location:index.php");
        exit;

    } else {

        echo "Wrong Username or Password";
        echo "<form name='form5' action='main_login.html'>";
        echo    "<input type='submit' name='Submit' value='Log-in'>";
        echo "</form>";

    }

/* close connection */
mysqli_close($link);

?>

【问题讨论】:

  • 您查看过mysqli_stmt_num_rows 文档吗? PS:为什么不用sqlCOUNT来代替呢?
  • 你需要在数据库中存储encrypted passwords

标签: php session mysqli mysql-num-rows


【解决方案1】:

+1 用于使用准备好的语句。

您需要先致电store_result,然后才能查看num_rows

mysqli_stmt_execute($stmt);
mysqli_stmt_store_result($stmt);
$count = mysqli_stmt_num_rows($stmt);

正如其他用户所建议的,确保您只在数据库中存储散列密码,而不是在 HTTP 请求中传输未加密的密码。您可以通过使用 JS 向表单添加输入、在登录表单上对密码进行哈希处理、使用 JS 删除未哈希密码字段并将表单中的哈希密码与数据库中的哈希密码进行比较来做到这一点。

另外,如果检查失败,您最好使用self-referencing forms,而不是为后续登录回显一个新表单,这种方法很快就会变得难以管理。

【讨论】:

  • 您好,感谢您的回复。我计划为密码添加加密。目前我还是 mysqli 的新手(最近在 Uni 完成,我们只使用 mysql php,而不是 mysqli)所以我确保在添加加密部分之前我已经掌握了基础知识。
  • 酷,祝你好运。看看面向对象的方式来表示准备好的语句 -> 使代码更清晰!
  • 嗨,如果你还在,Leemo。再次查看我的代码后,我看不出有任何理由保留“mysqli_stmt_bind_result”。据我所知,我实际上并不需要它,因为我从不使用它。此外, fetch 也将过时。是否有任何理由(我可能忽略了)我需要保留这些?
  • store_result 实际上不会产生任何检索任何值或将它们绑定到任何变量。 bind_result 分配变量以将结果传递给调用 fetch 时,因此您需要所有变量。
  • 我不经常使用 PHP,但是当我这样做时,我会浪费半个晚上想知道为什么明确返回结果的语句总是返回 0...
【解决方案2】:

+1 @leemo 先回答,但我会稍微扩展解释并标记我的答案 CW。

在获取所有行之前,MySQL 客户端无法知道结果集中有多少行。实际上,这并不是因为 PHP 的原因——即使您直接使用 MySQL 客户端库在 C 中编程也是如此。

所以你要么需要像@leemo 所说的那样使用mysqli_stmt_store_result(),它基本上将完整的结果集从服务器复制到客户端。

或者,您可以遍历mysqli_stmt_fetch(),直到您获取所有行。然后mysql_stmt_num_rows() 将返回正确的数字。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-01-12
    • 1970-01-01
    • 2017-10-08
    • 1970-01-01
    • 2013-12-23
    • 2012-02-12
    • 1970-01-01
    • 2012-08-04
    相关资源
    最近更新 更多