I can't seem to work out how to retrieve number of rows from the database using my query, whenever I run the query It just returns zero even though it's in my database
$username = $_POST['username'];
$hash = password_verify($password, $passwordcheck);
if($stmt = $conn -> prepare("SELECT username, email, password FROM users WHERE (username = ? OR email = ?) AND password = ?"))
{
$stmt -> bind_param("sss", $username, $username, $hash);
$stmt -> execute();
$stmt -> bind_result($checkedUsername, $checkedEmail, $checkedPassword);
$stmt -> fetch();
$numberofrows = $stmt->num_rows;
$stmt -> close();
}
echo '# rows: '.$numberofrows;
Can anyone give me any hints? Can't see to wrap my head around it, thanks.
Btw, the $hash has already been queried prior to this statement.
Posting this as a community wiki:
add $stmt->store_result(); after your execute()
As I assume you have used password_hash() on the password you store in the database. Then you should not be using it in a search criteria. Re-hashing the same string will not generate the same hash using password_hash() as it will use a different SALT each time its run Thats why its the recommended hashing tool.
So you need to do something like this
$username = $_POST['username'];
$stmt = $conn->prepare("SELECT username, email, password
FROM users WHERE (username = ? OR email = ?)")
if($stmt) {
$stmt->bind_param("ss", $username, $username);
$stmt->execute();
// As per #fred-ii- comment
$stmt->store_result();
$stmt->bind_result($checkedUsername, $checkedEmail, $checkedPassword);
$stmt->fetch();
echo '# rows: ' . $stmt->num_rows;
if ( password_verify($_POST['password'], $checkedPassword) ) {
// password is correct
} else {
// password is NOT correct
}
$stmt -> close();
}
Related
How can I turn this to PDO? I tried, but I don't know how.
It was MySQLi at first and I tried to turn it to PDO and so, that was the result:
<?php
$username = $_POST['username'];
$password = $_POST['password'];
$stmt = $conn-> prepare("SELECT * FROM resident WHERE '$username' = ? AND '$password' = ?");
//mysqli_stmt_bind_param($sql, "ss", $username, $password);
$stmt->bindParam(':username', $username);
$stmt->bindParam(':password', $password);
$stmt ->execute();
mysqli_stmt_store_result($sql);
$stmt-> BindParam($sql, $name, $username, $password);
$response=array();
$response["succes"] = false;
while (mysqli_stmt_fetch($sql)) {
$response["success"] = true;
$response["name"]= $name;
}
echo json_encode ($response);
?>
You're confusing variables with column names. It's extremely important to note the difference. In a query '$username' is a string with a value in it, and probably a SQL injection bug. username without quotes is probably a column name.
You're also using named placeholders but you haven't named them. ? is an unnamed one. If you want a placeholder named :x then :x must appear in the query.
Your fixed code should look like:
$stmt = $conn-> prepare("SELECT * FROM resident WHERE username=:username AND password=:password");
//mysqli_stmt_bind_param($sql, "ss", $username, $password);
$stmt->bindParam(':username', $username);
$stmt->bindParam(':password', $password);
$stmt ->execute();
That is technically functional but VERY, VERY WRONG. Passwords must be properly hashed using, at the absolute least, password_hash. If you do that you can no longer fetch based on username and password, you need to fetch based on username and use password_verify to check if it's correct or not.
Disclaimer: Don't Write Your Own Login System
Unless this is strictly for academic purposes, all of this code is pretty much a waste of time. Any development framework has a solution for this. One example is Laravel where out of the box you get a full-featured authentication system.
You can use answer of tadman, also this:
$stmt = $conn-> prepare("SELECT `id` FROM resident WHERE username=:username AND password=:password");
$stmt->execute(array(':username' => $username, ':password' => $password);
And hash your passwords.
You can learn some basics of pdo Here, W3schools
I was under the impression that this was a prepared statement script, but it appears I was wrong. How can I turn this into one? What is a prepared statement?
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
$sql = "SELECT Status FROM Users WHERE Username = ? AND Password = ?";
$stmt = $conn->prepare($sql);
$stmt->bind_param("ss", $_GET['username'], $_GET['password']);
$stmt->execute();
$result = $stmt->get_result();
$rows = $result->fetch_all(MYSQLI_ASSOC);
if ($result->num_rows > 0) {
// output data of each row or remove while loop if you wish
while($row = $result->fetch_assoc()) {
echo "<b style='color:green'>Found</b>";
}
} else {
echo "0 results";
}
$conn->close();
?>
That's not using prepared statements. This is a basic example with no error/result checking:-
$sql = "SELECT Status FROM Users WHERE Username = ? AND Password = ?";
$stmt = $conn->prepare($sql);
$stmt->bind_param("ss", $_GET['username'], $_GET['password']);
$stmt->execute();
$result = $stmt->get_result();
$rows = $result->fetch_all(MYSQLI_ASSOC);
However you should consider selecting on username only and retrieving the password for comparison. You should also hash your passwords in the database if you're not doing so. Use php's password_hash() and password_verify() for that. The former would help in hashing the password while the latter would be used to verify if the posted password from the html form or original source matches the hashed password
the syntax is
password_hash($_GET['password'], PASSWORD_DEFAULT);
password_verify($_GET['password'], $hashedPasswordFromDatabase);
make sure the column storing the password is varchar(60) at least.
The problem is, I have a statement like this one below and i use it in server side of my android app
$statement = mysqli_prepare($con, "SELECT * FROM accounts WHERE email = ? OR username = ?");
mysqli_stmt_bind_param($statement, "ss", $email, $username);
$result = mysqli_stmt_execute($statement);
$rows = mysqli_stmt_fetch($result);
And I want to know how many rows are back from it so I can know if there is already data in the database with the same username and email or not, but it doesn't work.
How to solve this problem? And thanks in advance.
And I want to know how many rows are back
Nope, you don't. That's a false goal.
When working with a database, you should always request the exact data you need, instead of doing some calculations on the client side.
So in your case you need the user info - so select that info. Means this very user info you can use to tell whether your query returned anything or not.
$statement = mysqli_prepare($con, "SELECT * FROM accounts WHERE email = ? OR username = ?");
mysqli_stmt_bind_param($statement, "ss", $email, $username);
mysqli_stmt_execute($statement);
$result = mysqli_get_result($statement);
$user = mysqli_fetch_assoc($result);
//now you have the very $user variable to tell whether anything was found
if ($user) {
//user exists
}
All you are missing is to use the num_rows function with the resulting mysqli object:
$statement = mysqli_prepare($con,
"SELECT * FROM accounts WHERE email = ? OR username = ?");
mysqli_stmt_bind_param($statement, "ss", $email, $username);
$result = mysqli_stmt_execute($statement);
$numbRows = $result->num_rows;
//printing the result:
echo "number of rows = {$numbRows}<br>";
I've gone through quite a number of stackoverflow threads and I simply can't get it right to retrieve the results after preparing a query. I've tried a number of different solutions and none seem to be able to fetch the associative array after I execute the query
$mysqli = new MySQLi('localhost', 'root', '', 'prac2');
$query = $mysqli-> prepare("SELECT * FROM `user` WHERE username=? and password=?");
$query-> bind_param('ii', $username, $password);
if($query-> execute()) {
$query->store_result();
if ($query -> num_rows > 0) {
$result = $mysqli->query($query);
$r = $result -> fetch_array(MYSQLI_ASSOC)['userid'];
$_SESSION['userid'] = $r;
}
}
I've established that sometimes its a case of result containing a boolean for success but I'm still not certain what exactly I'm doing wrong.
UPDATED:
Okay the bind_param works now, but the fetch_assoc keeps giving me the error "Call to a member function fetch_assoc() on a non-object", I even test the result to ensure that it returns true.
$mysqli = new MySQLi('localhost', 'root', '', 'prac2');
$query = $mysqli->prepare("SELECT * FROM user WHERE username=? and password=?");
echo $mysqli->error;
$query-> bind_param('ss', $username, $password);
if($query->execute()) {
$result = $query -> store_result();
if($result) {
while($row = $result -> fetch_assoc()){
echo $row['userid'];
$_SESSION['userid'] = $row['userid'];
}
}
}
Usernames and password are strings and it should be 's' denoting that corresponding variable has type string. I don't see how usernames and passwords are integers. Bind Param Types
$query-> bind_param('ss', $username, $password);
Inside bind_param for string you should use s. I mean try ss instead of ii.
For user registration, I want to make sure the username and emails aren't already in use. I have already connected to $mysqli somewhere else in the code.
$usr = $mysqli->real_escape_string($_POST['susername']);
$eml = $mysqli->real_escape_string($_POST['semail']);
$stmt = $mysqli->prepare("SELECT userid FROM users WHERE username=? || email=?");
$stmt->bind_param("is", $usr, $eml);
$stmt->execute();
$stmt->bind_result($count);
$stmt->close();
However, count contains nothing. How can I check if something already exists in the DB?
Change,
stmt = $mysqli->prepare("SELECT userid FROM users WHERE username=? || email=?");
To
stmt = $mysqli->prepare("SELECT count(userid) FROM users WHERE username=? || email=?");
Then you should fetch the value using fetch()
Is your username an integer? You can try the following code,
$stmt->bind_param("ss", $usr, $eml); //ss