我正在为我的Web应用程序创建一个登录脚本,并且我正在尝试使用$count = mysqli_stmt_num_rows($stmt);
来查找从sql select语句返回的行数,因此我可以决定是否应该启动会话。
问题是,即使我输入与我数据库中的数据匹配的有效用户名和密码,$ count也始终为0。我已经测试了select语句,它运行正常。没有给出任何错误,语法,SQL或其他内容,所以我对于发生的事情有点困惑。
CODE:
<?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);
?>
答案 0 :(得分:11)
+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而不是为后续登录回显新表单,这种方法将很快变得无法管理。
答案 1 :(得分:2)
+1 @leemo首先回答,但我会稍微扩展一下解释并标记我的答案CW。
MySQL客户端在获取所有行之前无法知道结果集中有多少行。这不是因为PHP,实际上 - 即使您使用MySQL客户端库直接在C中编程也是如此。
所以你需要使用mysqli_stmt_store_result()
作为@leemo说,它基本上将完整的结果集从服务器复制到客户端。
或者,您可以遍历mysqli_stmt_fetch()
,直到您获取所有行。然后mysql_stmt_num_rows()
将返回正确的号码。