I am creating a login script for my web app and am trying to use $count = mysqli_stmt_num_rows($stmt);
to find the number of rows returned from the sql select statement, so I can then decide if a session should be started.
The problem is, $count is always 0, even when I enter valid user name and password that matches the data in my database. I have tested the select statement, it works fine. No errors, syntax, SQL or otherwise are given, so i'm kinda stuck as to whats happening.
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);
?>
+1 for using prepared statements.
You need to call store_result
before you can check num_rows
:
mysqli_stmt_execute($stmt);
mysqli_stmt_store_result($stmt);
$count = mysqli_stmt_num_rows($stmt);
As other users have suggested ensure that you are only storing hashed passwords in the DB and not transferring unencrypted passwords in HTTP requests. You can do this by adding an input to the form with JS, hashing the password on the login form, remove the unhashed password field with JS and compare the hashed password from the form with the hashed password in the DB.
Also, if the check fails, you're better off using self-referencing forms than echoing out a new form for a subsequent login, this kind of approach will become unmanageable very quickly.
+1 to @leemo for answering first, but I'll expand the explanation a bit and mark my answer CW.
The MySQL client has no way of knowing how many rows are in the result set until it fetches all the rows. This is not because of PHP, actually -- it would be true even if you program in C using the MySQL client library directly.
So you either need to use mysqli_stmt_store_result()
as @leemo says, which basically copies the full result set from the server to the client.
Alternatively, you could loop over mysqli_stmt_fetch()
until you have fetched all rows. Then mysql_stmt_num_rows()
will return the right number.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With