This is the code, following (Explanation is afterwards):
<?php
error_reporting(E_ALL);
ini_set('display_errors',1);
$uname = $_POST['uname'];
if($uname!=""){
$mysqli = new mysqli('localhost', 'root', '', 'dota_site_test');
if(mysqli_connect_errno()){
echo("connetion error: " . mysqli_connect_errno());
exit();
}
$stmt = $mysqli->prepare("SELECT Username FROM users WHERE Username=?");
$stmt -> bind_param("s", $uname);
$stmt -> execute();
$stmt -> bind_result($unamecheck);
if($stmt->num_rows > 0){
echo "taken: ";
echo "name is ".$unamecheck;
}else{
echo "free: ";
echo "name is ".$unamecheck;
}
$stmt -> close();
$mysqli -> close();
}
?>
I am not sure where the problem is, but when I am, at the bottom, trying to echo "name is ". $unamecheck;, It is just returning blank. The way this code works is that on every key press the query is run to see if a Username is already present in the database. I have checked my Ajax, and the $uname = $_POST['uname']; is working fine.
In addition, I have ran the query "SELECT Username FROM users WHERE Username=?" within mysql itself, replacing the ? with my username, and that worked fine.
Have I made a mistake with the prepared statement? I am not sure if this is the way it must be done, but I am trying to be careful with SQL injection.
The result of my testing just shows free: name is being echo'd regardless of input. No other error codes are present.
You need to call
$stmt -> fetch();
After
$stmt -> bind_result($unamecheck);
In the prepare query, try to separete the =? from the column name, like this:
SELECT Username FROM users WHERE Username = ?
If this not work, print mysql_error() to verify if there is a mysql error
Related
I'm trying to make a login system with PHPMyAdmin and I seem to be having trouble with the bind function. It should print the records stored in the database of the account I log in with but instead I get this error from uwamp; Warning: mysqli_stmt::bind_param(): Number of variables doesn't match number of parameters in prepared statement in C:\UwAmp\www\Test\M2\Authentication.php on line 22
For reference, here's my code;
<?php
//Perameters needed to login to the database
$serverName= "localhost";
$DBUsername= "root";
$DBPassword= "root";
$DatabaseName="database 1";
//Connect to the database using the parameters
$conn = new mysqli($serverName, $DBUsername, $DBPassword, $DatabaseName);
//If there is a connection error, kill the connection and show said error.
if ($conn -> connect_error)
{
die("Connection fail: " . $conn -> connect_error);
}
//Query the table
$paramUsername = $_POST['InputUsername'];
$paramPassword = $_POST['InputPassword'];
$Statement= $conn-> prepare("SELECT UserID, Name, Username, Password, PrivilegeLevel FROM users WHERE Username AND Password= ?");
$Statement -> bind_param('ss', $paramUsername, $paramPassword);
$Statement -> execute();
$Statement -> store_result();
$Statement -> bind_result($UserId, $UtBLName, $UtBLUsername, $UtBLPassword, $PrivLevel);
$Statement -> fetch();
$Statement -> close();
?>
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
</head>
<body>
<div>
Your user ID is: <?php echo $UserId; ?> <br>
Your name is: <?php echo $UtBLName; ?> <br>
Your username is: <?php echo $UtBLUsername; ?> <br>
Your password is: <?php echo $UtBLPassword; ?> <br>
Your privilege level is: <?php echo $PrivLevel; ?> <br>
</div>
</body>
</html>
Now I have looked around on this site and found a thread that says I should change the number of S-es in the bind bind_param, so I changed it from one to two and it's still giving the same error. Any suggestions?
Your SQL
Username AND Password= ?
Is bad syntax. As you're providing two values, it should be:
Username = ? AND Password = ?
The bind_param call is placing X number of variables in X number of ? in the SQL, so the number of variables must always match the number of ? in the query.
Therefore:
$Statement= $conn-> prepare("SELECT UserID, Name, Username, Password, PrivilegeLevel FROM users WHERE Username = ? AND Password= ?");
// Two ? in the SQL mean two variables are required.
$Statement -> bind_param('ss', $paramUsername, $paramPassword);
Security
Passwords should NEVER be stored as plaintext in any medium. You can easily work around this using PHPs Password Hash mechanism which is Highly Encouraged.
$paramPassword = password_hash($_POST['InputPassword'],PASSWORD_DEFAULT);
I am trying to build an override feature so users can manually remove a MySQL table row if they have the correct rights to do so. The user is prompted to input the same credentials used for program login as well as the uniqueID for the row that needs to be removed. Upon hitting the 'Submit' function, I run a series of if statements/ MySQL SELECT statements to check credentials, user rights and finally row Deletion with the result output as an alert.
However, my alert shows up blank and the row is not removed so I know there is a problem with my if statements. Upon testing, I believe the problem is when I try to use the previous query's results to run the next if statement logic.
How do I properly determine if the MySQL query returned a row using prepared statements?
All help is appreciated! Thank you!
My CODE:
if ((isset($_POST['overrideUsername'])) and (isset($_POST['overridePassword'])) and (isset($_POST['overrideUniqueID']))) {
$overridePasswordInput = $_POST['overridePassword'];
$overrideUsername = $_POST['overrideUsername'];
$overridePassword = ENCODE(($overridePasswordInput).(ENCRYPTION_SEED));
$roleID = '154';
$overrideUniqueID = $_POST['overrideUniqueID'];
//connect to the database
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if(mysqli_connect_errno() ) {
printf('Could not connect: ' . mysqli_connect_error());
exit();
}
$conn->select_db($dbname);
if(! $conn->select_db($dbname) ) {
echo 'Could not select database. '.'<BR>';
}
$sql1 = "SELECT users.id FROM users WHERE (users.login = ?) AND (users.password = ?)";
$stmt1 = $conn->prepare($sql1);
$stmt1->bind_param('ss', $overrideUsername, $overridePassword);
$stmt1->execute();
$stmt1->bind_result($userID);
//$result1 = $stmt1->get_result();
if ($stmt1->fetch()) {
$sql2 = "SELECT * FROM rolestousers WHERE (rolestousers.userid = ?) AND (rolestousers.roleid = ?)";
$stmt2 = $conn->prepare($sql2);
$stmt2->bind_param('ss', $userID, $roleID);
$stmt2->execute();
$stmt2->store_result();
if ($stmt2->fetch()) {
$sql3 = "DELETE * FROM locator_time_track_out WHERE locator_time_track_out.uniqueid = ?";
$stmt3 = $conn->prepare($sql2);
$stmt3->bind_param('s', $overrideUniqueID);
$stmt3->execute();
$stmt3->store_result();
if ($stmt3->fetch()) {
echo 'Override Successful! Please scan the unit again to close it out.';
} else {
echo 'Could Not Delete Record from the table.';
}//End $sql3 if.
} else {
echo 'User does not have override permission. Please contact the IT Department.';
}//End $sql2 if.
} else {
echo 'Your login information is incorrect. Please try again. If the issue persists, contact the IT Department.';
}//End $sql1 if.
//Free the result variable.
$stmt1->free();
$stmt2->free();
$stmt3->free();
$stmt1->close();
//Close the Database connection.
$conn->close();
}//End If statement
NOTE: I am definitely sure my DB connection information is correct. The issue resides after I connect into the database. I have also tested the code using only the first if statement and get the blank alert so I'm not making it past the first if statement.
EDIT:: My php Script was definitely failing, but even earlier than expected, at the following code:
$overridePassword = ENCODE(($overridePasswordInput).(ENCRYPTION_SEED));
So my issue is that I need to properly compare the password and encryption seed information. However, the previous programmer used the following line to do the same process (which is obviously unsafe):
$querystatement = "SELECT id, firstname, lastname, email, phone, department, employeenumber, admin, usertype FROM users WHERE login=\"".mysql_real_escape_string($user)."\" AND password=ENCODE(\"".mysql_real_escape_string($pass)."\",\"".mysql_real_escape_string(ENCRYPTION_SEED)."\")";
$queryresult = $this->db->query($querystatement);
I will need to fix this issue before I can even test the functionality of the if logic using prepared statements.
Your are passing wrong variable for delete query
$stmt3 = $conn->prepare($sql3);
Please refer [ http://www.plus2net.com/php_tutorial/pdo-delete.php ]
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();
}
I have this code
$con = new mysqli('####', '####', '####', '####');
if(mysqli_connect_errno()){
echo 'Connection Failed:' . mysqli_connect_errno();
exit();
}
//Variables
$user = $_POST['username'];
$zone = $_POST['password'];
$pass = strtoupper(hash("whirlpool", $zone));
//Prepare
if($stmt = $con -> prepare("SELECT * FROM `accounts` WHERE Username=? AND Key=?")){
$stmt -> bind_param("ss", $user, $pass);
$stmt -> execute();
$stmt -> bind_results($result);
$stmt -> fetch();
if($result) {
$_SESSION['username'] = $user;
$url = 'home.php';
echo '<META HTTP-EQUIV=Refresh CONTENT="1; URL='.$url.'">';
} else {
echo 'Login Failed';
}
}
?>
I am new to Prepared statements and I cannot get it to work.
Upon trying to log in I just get a blank white page with no error. I know I am connected to the db because if I remove the prepared statement and do it the unsecured way everything logs in just fine.
Please note. I have just been looking up tutorials on prepared statements so I can learn to code more securely. I am in no way a pro with this. Any tips would be greatly appreciated.
Warning: mysqli_stmt::bind_result(): Number of bind variables doesn't
match number of fields in prepared statement in
C:\xampp\htdocs\newsystem\loginadd.php
That's because you select * (all fields). You should be more specific about the fields you want to get (for example SELECT id FROM ...).
Have a look at examples on PHP doc: 2 fields are selected, 2 parameters for bind_result().
According to #AbrikChakraborty comment you just need add backticks to your field name:
if($stmt = $con -> prepare("SELECT * FROM `accounts` WHERE Username=? AND `Key`=?")){
and according to #caCtus comment:
$stmt -> bind_result($result);
and if you really want to bind unknown number of fields returned you can check this answer or just use PDO.
Verify the actual query, if it fetches the result. I doubt the query itself returns empty result.
"SELECT * FROM `accounts` WHERE Username=$user AND Key=$pass"
I'm trying to get to grips with mysqli but finding it a struggle compared to the now depreciated mysql. So far with the old methods I've been able to get information back about my tables in an associative array. I'm trying to form a prepared statement and echo the id number back. I would also like to be able to print the whole sql statement that has been binded, but seen as I can't even echo the id number from a single SELECT statement, it is out of the question at the moment.
$db = new mysqli('xxx', 'xx', 'xx', 'xxxx');
$sql = "SELECT user_id, name FROM users WHERE name=?"
$statement = $db -> prepare($sql);
$statement -> bind_param("s", "Emma");
$statement -> execute();
$statement -> bind_result($id, $name);
$output = $statement -> fetch();
echo $output -> $id . " " . $name;
I seem to be getting lost at the line bind_result. I figured if statement is an object, then I should be able to echo them in the form I have devised? When I refresh my page I just get nothing. I have 2 entries in my table and 1 of them does have the name string that is used above.
You think too complex. Just try this:
$db = new mysqli('xxx', 'xx', 'xx', 'xxxx');
$sql = "SELECT user_id, name FROM users WHERE name=?";
$statement = $db->prepare($sql);
$statement->bind_param("s", "Emma");
$statement->execute();
$statement->bind_result($id, $name);
while ($statement->fetch()) {
echo $id . " " . $name;
}
The bind_result() methods takes care that for each $statement->fetch() you execute you get fresh values in the variables $id and $name.
You should take a look at the good documentation of those methods.