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
Related
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 a MySQL query which works from the command line, but not from PHP.
Can anyone see what I am doing wrong?
$sqlText = 'SELECT FROM customers WHERE login_name=:name
AND password=:password';
$query = $pdo->prepare($sqlText);
$query->bindParam(':name', $userName);
$query->bindParam(':password', sha1($password));
$result = $query->fetch(PDO::FETCH_ASSOC);
and $result is false.
But, from the command line,
SELECT * FROM customers WHERE login_name="a"
AND password="4192dee2f886e99ececbb2eee0d2f37f11257974"
works.
When I debug userName is a and $password is 4192dee2f886e99ececbb2eee0d2f37f11257974.
Can some one make me say D'oh ?
You've forgotten about execute I suppose:
$sqlText = 'SELECT FROM customers WHERE login_name=:name AND password=:password';
$query = $pdo->prepare($sqlText);
$hash = sha1($password);
$query->bindParam(':name', $userName);
$query->bindParam(':password', $hash);
$query->execute();
$result = $query->fetch(PDO::FETCH_ASSOC);
You forgot execute().
Moreover, if really $password` is `4192dee2f886e99ececbb2eee0d2f37f11257974, then you must be running sha1() twice. Either remove the sha1() from the bind line, or keep $password in the clear.
I'd suggest naming the database column "passwordHash", and the variable either $password if it is in cleartext, or $passwordHash if you already ran sha1() on it. That way, you would have written
$query->bindParam(':passwordHash', sha1($passwordHash));
and immediately spotted the extra sha1() call.
you have to call $query->execute(); to execute the query in PDO
$sqlText = 'SELECT FROM customers WHERE login_name=:name AND password=:password';
$query = $pdo->prepare($sqlText);
$query->bindParam(':name', $userName);
$query->bindParam(':password', sha1($password));
$query->execute();
$result = $query->fetch(PDO::FETCH_ASSOC);
The prepare method only prepares the sql statement you passed in and returns a preparedstatement object.
As mentioned above, you need to set the params and execute it to get the resultset back.
The advantages of prepared statement besides the security is that you can repeatedly assign parameters and execute a preparedstatement which is considered to be faster than compiling the same sql query string again and again.
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>";
Fatal error: Call to a member function prepare() on a non-object in
/home/melazabi/public_html/assigment/The/include/process.php on line
15
// check if the username exists in the database
// line 15 is the one below:
$statement = $conn->prepare("select * from users where username=? AND password=?");
//prepare statment is to try to stop sql injection
$statement->bindParam(1, $un);
$statement->bindParam (2, $pw);
$statement->execute();
As per what you shown in your comment:
You're using a mysql_* based connection
$conn = mysql_connect('localhost','admin','admin') or die("error2"); mysql_select_db("admin") or die("error");
with a PDO query.
You need to use: (replace with actual DB credentials)
$dbname = 'admin';
$username = 'admin';
$password = 'admin';
$conn = new PDO("mysql:host=localhost;dbname=$dbname", $username, $password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
The error is telling you the your query failed for any number of reasons.
Your db connection failed, either authentication problem or complete failure to connect.
Your params are not defined correctly.
you can debug this by
print_r($statement->errorInfo());
this will give you what the error returned by sql was.
also make user variables are set. If i were to guess not having seen the rest of your code. you probably want $_POST['un'] and $_POST['pw']
echo $un;
echo $pw;
edit
connect to db:
$conn = new PDO('mysql:host='SERVERADDRESS';dbname=DBNAME;charset=utf8', 'USERNAME', 'PASSWORD');
then your query
$statement = $conn->prepare("select * from users where username=? AND password=?");
//prepare statment is to try to stop sql injection
$statement->bindParam(1, $un);
$statement->bindParam (2, $pw);
$statement->execute();
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