Fetching results from a prepared select query - php

I'm trying to create a basic log-in system. Username and password are entered into a form and the results are sent to this page. If I enter the correct details, it works fine, but if I try to log-in with nonsense it never displays the error message. The line seems to be skipped every single time.
if(isset($_POST['submit'])) {
$sql = "SELECT username,password FROM tbl_users WHERE username = ? AND password = ?";
$stmt = $mysqli->prepare($sql);
if(!$stmt) {
die("Prepare failed: (" . $mysqli->errno . ") " . $mysqli->error);
}
$username = $_POST['username'];
$password = $_POST['password'];
$bind_result = $stmt->bind_param("ss", $username, $password);
if(!$bind_result) {
echo "Binding failed: (" . $stmt->errno . ") " . $stmt->error;
}
$execute_result = $stmt->execute();
if(!$execute_result) {
echo "Execute failed: (" . $stmt->errno . ") " . $stmt->error;
}
$stmt->bind_result($returned_username, $returned_password);
while($stmt->fetch()) {
if($_POST['username'] == $returned_username && $_POST['password'] == $returned_password) {
echo "You are now logged in!";
} else {
echo "Incorrect username or password";
}
}
echo $stmt->fetch();
include 'disconnect.php';
}

this should work...
$username = $_POST['username'];
$password = $_POST['password'];
$sql = "SELECT password FROM tbl_users where username = ?";
$stmt= $conn->prepare($sql);
$result->bind_param('s',$username);
$result->execute();
$result->bind_result($pass);
$stmt->fetch()
// echo "<pre>"; print_r($pass);
if($pass == $password) {
echo "You are now logged in! <br><br>";
}
else{
echo 'Incorrect username or password<br>';
}
comment if not working...

Related

I have a php register page where I want to return errors in case there are any

my php code checks for example if the username that is introduced by the user is already in use. If so I want to diplay an error at the bottom of the register form that sais so. Is there any way to do this only by using html,css,php?
This is my php code
<?php
if (isset($_POST["submit-register"])) {
require "dbh.inc.php";
$fname = $_POST["FirstName"];
$lname = $_POST["LastName"];
$username = $_POST["uid"];
$email = $_POST["mail"];
$password = $_POST["pwd"];
$passwordRepeat = $_POST["pwd-repeat"];
if (empty($username) || empty($email) || empty($password) || empty($passwordRepeat) || empty($fname) || empty($lname)) {
header("Location: ../register.php?error=emptyfields&uid=" . $username . "&mail=" . $email);//returning Emoty fields error
exit();
} else if (!filter_var($email, FILTER_VALIDATE_EMAIL) && !preg_match("/^[a-zA-Z0-9]*$/", $username) && !preg_match("/^[a-zA-Z]*$/", $fname) && !preg_match("/^[a-zA-Z]*$/", $lname)) {
header("Location: ../register.php?error=invalidemailandusername");//returning invalid email and username error
exit();
} else if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
header("Location: ../register.php?error=invalidemail&uid=" . $username . "&FirstName=" . $fname . "&LastName=" . $lname);//returning only invalid email error
exit();
} else if (!preg_match("/^[a-zA-Z0-9]*$/", $username)) {
header("Location: ../register.php?error=invalidusername&mail=" . $email . "&FirstName=" . $fname . "&LastName=" . $lname);//returning invalid username error
exit();
} else if (!preg_match("/^[a-zA-Z]*$/", $fname)) {
header("Location: ../register.php?error=invalidFirstName&mail=" . $email . "&uid=" . $username . "&LastName=" . $lname);//returning invalid first name error
exit();
} else if (!preg_match("/^[a-zA-Z]*$/", $lname)) {
header("Location: ../register.php?error=invalidLastName&mail=" . $email . "&uid=" . $username . "&FirstName=" . $fname);//returning invalid last name error
exit();
} else if ($password !== $passwordRepeat) {
header("Location: ../register.php?error=passwordsdonotmatch&uid=" . $username . "&mail=" . $email . "&FirstName=" . $fname . "&LastName=" . $lname);//returning passswords do not match error
exit();
} else {
$sql = "SELECT uidUsers FROM users WHERE uidUsers=?";
$sqlemail = "SELECT emailUsers FROM users WHERE emailUsers=?";
$stmt = mysqli_stmt_init($conn);
if (!mysqli_stmt_prepare($stmt, $sql)) {
header("Location: ../register.php?error=sqlerror&mail=" . $email);
exit();
} else {
mysqli_stmt_bind_param($stmt, "s", $username);
mysqli_stmt_execute($stmt);
mysqli_stmt_store_result($stmt);
$resultCheck = mysqli_stmt_num_rows($stmt);
if ($resultCheck > 0) {
header("Location: ../register.php?error=useralredadytaken&mail=" . $email);//returning username already taken error
exit();
} else {
if (!mysqli_stmt_prepare($stmt, $sqlemail)) {
header("Location: ../register.php?error=sqlerror&mail=" . $uid);
exit();
} else {
mysqli_stmt_bind_param($stmt, "s", $email);
mysqli_stmt_execute($stmt);
mysqli_stmt_store_result($stmt);
$resultCheck = mysqli_stmt_num_rows($stmt);
if ($resultCheck > 0) {
header("Location: ../register.php?error=emailalredadyinuse&uid=" . $username);//returning email taken error
exit();
} else {
$sql = "INSERT INTO users (uidUsers, emailUsers, pwdUsers, fnUsers, lnUsers) VALUES (?, ?, ?, ?, ?)";
$stmt = mysqli_stmt_init($conn);
if (!mysqli_stmt_prepare($stmt, $sql)) {
header("Location: ../register.php?error=sqlerror");
exit();
} else {
$hashedpassword = password_hash($password, PASSWORD_DEFAULT);
mysqli_stmt_bind_param($stmt, "sssss", $username, $email, $hashedpassword, $fname, $lname);
mysqli_stmt_execute($stmt);
header("Location: ../login.php?register=succes");
exit();
}
}
}
}
}
}
mysqli_stmt_close($stmt);
mysqli_close($conn);
} else {
header("Location: ../register.php");
exit();
}
The register page
And if it is possible I would like to return the fields that were introduced corectly back to the register page in the inputs. So the user does not have to complete the whole form again. Only the part that gave the error and the password.
Most times when I validate forms I put the errors in an array.
Put the php code and the form in 1 php file.
I use only if statements like
$errors = [];
if ($fname == '') {
$errors[] = 'Enter your firstname!';
}
if ($lname == '') {
$errors[] = 'Enter your lastname!';
}
Before adding a user to the database you check if errors is empty
if (empty($errors)) {
// add user
}
In the html form ill do a loop through my errors array
foreach ($errors as $error) {
echo '<p>' . $error . '</p>';
}
Before the if (isset($_POST["submit-register"])) { you can also do
$fname = isset($_POST['fname ']) ? $_POST['fname '] : '';
In your form you can use $fname in the value tag so the user don't have to reenter every thing

php mysqli non prepared to prepare statement

so i have a login page which works very well using php mysqli, but is non prepare so i usually use mysqli_real_escape to secure the data.
But am now migrating to using prepared statement, have manage this with my register page and this as work very well.
here is my non prepared login code:
$loginQuery = "select * from user where user_name = '$user_name' AND password = '$password'";
$result = mysqli_query($con,$loginQuery);
if(mysqli_num_rows($result)){
$row = mysqli_fetch_array($result);
// password verify
if (password_verify($password, $row['password'])) {
$_SESSION['user_id'] = $row['id'];
$_SESSION['user_name'] = strtoupper($row['user_name']);
$user_type = strtolower($row['user_type']);
if(strtolower($user_type) == 'member'){
$_SESSION['user_type'] = 'member';
//header('Location: member-dashboard-home.php');
header('Location: profile.php');
}elseif(strtolower($user_type) == 'admin' || strtolower($user_type) == 'leader'){
$_SESSION['user_type'] = strtolower($user_type);
//header('Location: admin-dashboard-home.php');
header('Location: profile.php');
}
}else{
$_SESSION['main_notice'] = "Invalid login details!";
header('Location: '.$_SERVER['PHP_SELF']);exit();
}
And below is my effort in using prepared statement.
$stmt = $mysqli->prepare("SELECT user_name FROM user WHERE user_name = ? ");
$stmt->bind_param('s', $user_name);
$stmt->execute();
$stmt->bind_result($user_name);
if($res = $stmt->num_rows()){
$row = $stmt->fetch_array($res);
// password verify
if (password_verify($password, $row['password'])) {
$_SESSION['user_id'] = $row['id'];
$_SESSION['user_name'] = strtoupper($row['user_name']);
$user_type = strtolower($row['user_type']);
if(strtolower($user_type) == 'member'){
$_SESSION['user_type'] = 'member';
//header('Location: member-dashboard-home.php');
header('Location: profile.php');
// exit;
}elseif(strtolower($user_type) == 'admin' || strtolower($user_type) == 'leader'){
$_SESSION['user_type'] = strtolower($user_type);
//header('Location: admin-dashboard-home.php');
header('Location: profile.php');
//exit;
}
}else{
$_SESSION['main_notice'] = "Invalid username OR password details, please try again!";
header('Location: '.$_SERVER['PHP_SELF']);exit();
}
}
I didn't get any error code when i tried to login, but the form just return blank and didn't redirect to user profile.
I don't think this is redirection issue tho or is it?
i don't i arrange the $stmt properly, hopefully you guy see what i can't.
thanks in advance
From your comment,
i did include at the top and i receive this error Notice: Undefined variable: mysqli in /home/connection.php... ...
Look at your code here,
$con = new mysqli("localhost", "***", "***", "***");
if ($mysqli->connect_errno) {
^^^^^^^^^^^^^^^^^^^^^^
echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^
}
Your connection handler is $con, not $mysqli, it should be like this:
$con = new mysqli("localhost", "***", "***", "***");
if ($con->connect_errno) {
echo "Failed to connect to MySQL: (" . $con->connect_errno . ") " . $con->connect_error;
}
Update(1): Change your code in the following way,
$stmt = $con->prepare("SELECT * FROM user WHERE user_name = ? ");
$stmt->bind_param('s', $user_name);
$stmt->execute();
$result = $stmt->get_result();
if($result->num_rows){
// username exists
$row = $result->fetch_array();
// your code
}else{
// username doesn't exist
// your code
}

Error with php and mysql, constant == variable returns false even tho they are the same

Okay so I am really really confused right now, the php script successful prints the user data, however when validating against the data submitted the script will return an error. For example when
if ($uname = $checkuname){
It will return the else function, if I set it to
if ($uname = $uname){
it will successfully do that but return an error on the password. Could someone please help me and tell me what I am doing wrong
Also how would I hash and salt a password the same way they were done in the database. Thank you :)
$uname = "username";
$pwrd = "c2c1e68b386e1f9087dd0b8ff1334a56573cef54";
// Create connection
$conn = new mysqli($server, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$sql = "SELECT id_group, member_name, passwd FROM smfrh_members WHERE member_name = '$uname'";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
// output data of each row
while($row = $result->fetch_assoc()) {
echo "id: " . $row["id_group"]. " - Name: " . $row["member_name"]. " " . $row["passwd"]. "<br>";
print $uname;
}
} else {
echo "0 results";
}
$checkuname = $row["member_name"];
$checkpwrd = $row["passwd"];
$checkgroup = $row["id_group"];
if ($uname == $checkuname){
if ($pwrd == $checkpwrd){
if ($checkgroup == "9"){
echo "success";
} else {
if ($checkgroup == "1"){
echo "OMG An ADMIN!";
} else {
echo "Sorry you are not a premium member";
}
}
} else {
echo "Your password was incorrect";
}
}
else{
echo "Your username could not be found";
}
$conn->close();
?>
You are trying to assign variables with an array that doesn't exist anymore, and therefore your variables: $checkuname, $checkpwd and $checkgroup are all set to null.
$checkuname = $row["member_name"];
$checkpwrd = $row["passwd"];
$checkgroup = $row["id_group"];
The $row array was created within the while loop while($row = $result->fetch_assoc()), and is only then accessible within that loop. You are then trying to access $row later on.
As, in theory, you are only expecting 1 row back - as it is a username / password situation - you can move the above assignments into the while loop.
Maybe something like this will work, in the if statement always use == instead of =
"==" means the check for exact the same like "42" == "42"
"=" means the check for the same data like "42" = 42
//Set variables
$uname = "username";
$pwrd = "c2c1e68b386e1f9087dd0b8ff1334a56573cef54";
// Create connection
$conn = new mysqli($server, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) die("Connection failed: " . $conn->connect_error);
//Declare SQL statement
$sql = "SELECT id_group, member_name, passwd FROM smfrh_members WHERE member_name = '$uname'";
//Catch result
$result = $conn->query($sql);
//Check for result
if ($result->num_rows > 0) {
// output data of each row
while($row = $result->fetch_assoc()) {
echo "id: " . $row["id_group"]. " - Name: " . $row["member_name"]. " " . $row["passwd"]. "<br>";
print $uname;
}
} else echo "0 results";
//Put result into variables
$checkuname = $row["member_name"];
$checkpwrd = $row["passwd"];
$checkgroup = $row["id_group"];
if ($uname == $checkuname && $pwrd == $checkpwrd){
if ($checkgroup = "9") echo "success";
else if ($checkgroup = "1") echo "OMG An ADMIN!";
else echo "Sorry you are not a premium member";
}
if ($uname != $checkuname) echo "Your username could not be found";
if ($pwrd != $checkpwrd) echo "Your password was incorrect";
$conn->close();
?>
Solution, I defined the $check* before in the script.
// Create connection
$conn = new mysqli($server, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) die("Connection failed: " . $conn->connect_error);
//Declare SQL statement
$sql = "SELECT id_group, member_name, passwd FROM smfrh_members WHERE member_name = '$uname'";
//Catch result
$result = $conn->query($sql);
//Check for result
if ($result->num_rows > 0) {
// output data of each row
while($row = $result->fetch_assoc()) {
$checkuname = $row["member_name"];
$checkpwrd = $row["passwd"];
$checkgroup = $row["id_group"];
echo "id: " . $checkgroup. " - Name: " . $checkuname. " " . $checkpwrd . "<br>";
}
} else echo "0 results";
//Put result into variables
if ($uname == $checkuname && $pwrd == $checkpwrd){
if ($checkgroup == "9") echo "success";
else if ($checkgroup == "1") echo "OMG An ADMIN!";
else echo "Sorry you are not a premium member";
}
if ($uname != $checkuname) echo "Your username could not be found";
if ($pwrd != $checkpwrd) echo "Your password was incorrect";
$conn->close();
?>

Handling no results returned from a prepared select statement

I'm trying to make a basic login system. User enters username + password in a form which is then posted and used in the following code:
if(isset($_POST['submit'])) {
$sql = "SELECT username, password FROM tbl_users WHERE username = ? AND password = ?";
$stmt = $mysqli->prepare($sql);
if(!$stmt) {
die("Prepare failed: (" . $mysqli->errno . ") " . $mysqli->error);
}
$username = $_POST['username'];
$password = $_POST['password'];
var_dump($username);
var_dump($password);
$bind_result = $stmt->bind_param("ss", $username, $password);
if(!$bind_result) {
echo "Binding failed: (" . $stmt->errno . ") " . $stmt->error;
}
$execute_result = $stmt->execute();
if(!$execute_result) {
echo "Execute failed: (" . $stmt->errno . ") " . $stmt->error;
}
$stmt->bind_result($returned_username, $returned_password);
while($stmt->fetch()) {
var_dump($returned_username);
var_dump($returned_password);
if($username === $returned_username && $password === $returned_password) {
echo "You are now logged in!";
} else {
echo "Incorrect username or password";
}
}
If I type in the correct username and password, everything works fine and it logs in correctly. The problems start to arise when I enter incorrect information, either using the wrong password or a username that isn't in the database. The "incorrect username or password" line has never worked at all.
My understanding of prepared statements are that once I bind the results, I can only access them in the while loop using fetch. However, if no results are found, that loop will never run, so I have no way of testing whether the query found any results or not.
I am suggest to you, use it like this:
if (isset($_POST['submit'])) {
//Checking, is a user exists with these credentials?
$sql = "SELECT COUNT(*) AS cnt FROM tbl_users WHERE username = ? AND password = ?";
$stmt = $mysqli->prepare($sql);
if (!$stmt) {
die("Prepare failed: (" . $mysqli->errno . ") " . $mysqli->error);
}
$bind_result = $stmt->bind_param("ss", $_POST['username'], $_POST['password']);
if (!$bind_result) {
echo "Binding failed: (" . $stmt->errno . ") " . $stmt->error;
}
$execute_result = $stmt->execute();
if (!$execute_result) {
echo "Execute failed: (" . $stmt->errno . ") " . $stmt->error;
}
$stmt->bind_result($cnt);
$stmt->fetch();
if ($cnt > 0) {
echo "You are now logged in!";
} else {
echo "Incorrect username or password";
}
}
The problem you're having is based in the logic implemented in your code. If no user is retrieve from the database then the code that checks for the correct username and password is never run, just by changing a few lines of your code you can fix that, try this:
//this is your code at the moment
while($stmt->fetch()) {
var_dump($returned_username);
var_dump($returned_password);
if($username === $returned_username && $password === $returned_password) {
echo "You are now logged in!";
} else {
echo "Incorrect username or password";
}
}
//replace that for this
while($stmt->fetch()) {
var_dump($returned_username);
var_dump($returned_password);
}
if($username === $returned_username && $password === $returned_password) {
echo "You are now logged in!";
} else {
echo "Incorrect username or password";
}
How about testing if you get any results, and if you don't throw error:
if($stmt->fetch())
{
do {
var_dump($returned_username);
var_dump($returned_password);
if($username === $returned_username && $password === $returned_password) {
echo "You are now logged in!";
} else {
echo "Incorrect username or password";
}
} while($stmt->fetch());
}
else
{
echo "Incorrect username or password";
}

user is already taken?

I have this code:
$username = $_POST["username"];
$password_input = $_POST["password"];
$password = md5($password_input);
$email_input = $_POST["emailaddress"];
$email = md5($email_input);
if (!($stmt = $con->prepare("INSERT INTO `users` (`username`,`password`,`email_address`) VALUES (?,?,?)")) || !is_object($stmt)) {
die( "Error preparing: (" .$con->errno . ") " . $con->error);
}
$stmt->bind_param('sss', $username, $password, $email);
$stmt->execute();
$stmt->close();
echo "User has been Created! Feel free to login - <a href='login.php'><span class='button color_blue'>Login</span></a>";
Within the SQL database an email/username can only be used once (UNIQUE) and I wondered if there was a way to change the echo to only appear if the data was successfully added and then a different message for if it wasn't successful.
Thanks - I'm still a rookie!
EDIT: so after using some code from the answer i am now at:
$username = $_POST["username"];
$password_input = $_POST["password"];
$password = md5($password_input);
$email_input = $_POST["emailaddress"];
$email = md5($email_input);
if (!($stmt = $con->prepare("INSERT INTO `users` (`username`,`password`,`email_address`) VALUES (?,?,?)")) || !is_object($stmt)) {die( "Error preparing: (" .$con->errno . ") " . $con->error);}
$stmt->bind_param('sss', $username, $password, $email);
$stmt->execute();
$stmt->close();
if ($con->affected_rows == 1) {echo "User has been Created! Feel free to login - <a href='login.php'><span class='button color_blue'>Login</span></a>";}
var_dump($con->affected_rows);
successful and unsuccessful INSERTS for some reason all have -1 as their "affected rows" output
The execute() method returns true if successful.
Replace:
$stmt->execute();
with:
if($stmt->execute()) {
echo "user created!";
} else {
echo "error: " . $stmt->error;
}
Yes, you just have to check if the query was successful or not:
change the end of your code by this:
$success = $stmt->execute();
$stmt->close();
if ($success)
echo "User has been Created! Feel free to login - <a href='login.php'><span class='button color_blue'>Login</span></a>";
else
echo "Impossible to create that user: ".$stmt->error;
To provide many different messages I work with flags. Simply say: if the username equals an existing db name, userExistMsg = 1.
To check if the User Exists, simply use a SELECT query in sql and ask for any entrys on the given user. This query should result in none obkects if the username is free.
Btw. You seem to use simple md5 for pw encoding. That's not verry secure. Better use something like salted passwords.
To check for successful UPDATE/INSERT/DELETE query, you would need to check if returned affected rows are more than zero.
http://php.net/mysqli_affected_rows
Returns the number of rows affected by the last INSERT, UPDATE,
REPLACE or DELETE query.
In your case:
if ($con->affected_rows == 1) {
echo "User has been Created! Feel free to login - <a href='login.php'><span class='button color_blue'>Login</span></a>";
}
Try this. This is a sample answer change this according to your code..
$username = $_POST["username"];
$password_input = $_POST["password"];
$password = md5($password_input);
$email_input = $_POST["emailaddress"];
$email = md5($email_input);
$con=mysqli_connect("HOST","USER","PASSWORD","your_db");
// Check connection
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
$result = mysqli_query($con,"SELECT COUNT(username) FROM users WHERE username = $username ");
$datacount2 = mysql_num_rows($result );
if($datacount2 < 1)
{
if (!($stmt = $con->prepare("INSERT INTO `users` (`username`,`password`,`email_address`) VALUES (?,?,?)")) || !is_object($stmt)) {
die( "Error preparing: (" .$con->errno . ") " . $con->error);
}
$stmt->bind_param('sss', $username, $password, $email);
$stmt->execute();
$stmt->close();
if($stmt)
{
echo "User has been Created! Feel free to login - <a href='login.php'><span class='button color_blue'>Login</span></a>";
}
else
{
echo "Insert Failed";
}
}
else
{
echo "User already exists..";
}
You could use mysqli_stmt::affected_rows to find out if rows were affected. If not, you can print out your error message

Categories