I'm using PDO for a connection into my db. There, I have a table where I store the users. In that table I have 5 columns: id, username, password, mail and sex.
What I really want is to store in a SESSION variable, the sex of the user that has been logged in. I don't know exactly what to use, because all the examples that I've seen, are usually for printing all the results of the db into the webpage with a foreach statement, but that isn't what I want.
Actually, this is the code that I have:
$connection = new PDO('mysql:host=localhost;dbname=db', "user", "password");
$sql = 'SELECT * FROM users WHERE username = :username AND password = :password';
$statement = $connection->prepare($sql);
$statement->bindParam(':username', $_POST['username'], PDO::PARAM_STR, 12);
$statement->bindParam(':password', $_POST['password'], PDO::PARAM_STR, 30);
$result = $statement->execute();
if ($result) {
$result = $statement->fetchAll();
if (!empty($result)){
$_SESSION['login'] = true;
$_SESSION['username'] = $_POST['username'];
echo 'Hello '.$_POST['username'].', you have been connected successfully.';
}
else {
echo 'Sorry, this user do not exist.';
}
}
So, this is correctly working.
But now, what I want is to store the sex value from the db in a $_SESSION['sex'] variable. How can I do that?
Thanks.
You can just add in the session after username, you have already slected from your query
$_SESSION['username'] = $_POST['username'];
$_SESSION['sex'] = $result[0]['sex'];
You might want to remove $result from query execution, so this line
$result = $statement->execute();
Will be
$statement->execute();
Just assign it from the result row:
$_SESSION['sex'] = $result[0]['sex'];
You have to use [0] because you used fetchAll, which returns a 2-dimensional array of rows and columns.
Related
I am trying to see if a code stored in my database is the same as the one the user provides, currently
user would provide the vCode via POST but i have it set to what it actually is for testing purposes
$vCode = "69582";
Now i'm using a PDO query to get the vCode that's in the database.
$dsn1 = "mysql:dbname={$this->dbDatabaseName};host={$this->dbHostname};";
$conn1 = new PDO($dsn1, $this->user, $this->password);
$conn1->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql1 = "SELECT * FROM `accinfo` WHERE Email = :email AND vCode = :vCode";
$stmt1 = $conn1->prepare($sql1);
$stmt1->bindParam(':email', $email, PDO::PARAM_STR);
$stmt1->bindParam(':vCode', $vCode, PDO::PARAM_STR);
$stmt1->execute();
if( $stmt1->rowCount() > 0 ) {
$result = $stmt1->setFetchMode(PDO::FETCH_ASSOC);
foreach(new TableRows(new RecursiveArrayIterator($stmt1->fetchAll())) as $k=>$v) {
$actualVCode = $v;
}
Then i see if the vCode i got from the database ($actualVCode) is equal to the $vCode
if ( $actualVCode == $vCode ){
echo "match";
}
The value stored in my database is a string and is 69582, but whenever i compare them like i do above, the if statement never comes back as true. But when i echo both $vCode and $actualVCode, they both are 69582.
Instead of getting the result from the first query and checking the result with the vCode, i've modified the query to select the whole row only if the email AND the vCode matches
$sql1 = "SELECT * FROM `accinfo` WHERE Email = '$email' AND vCode = '$vCode'";
$stmt1 = $conn1->prepare($sql1);
$stmt1->execute();
if( $stmt1->rowCount() > 0 ) {
//found match
echo "found match";
}
Im creating a webpage for a game server that only had a registration page. All the users has registred and for some dum reason, it saved the password as username:password, so if the username is Meko and password is 1234, the actually password is "Meko:1234" Im now trying to make a login but im not sure how I should check that password. I have this sql query and tried to add $user_username: in front, but it didnt seem to work:
$query = "SELECT * FROM account
WHERE username = '$user_username'
AND sha_pass_hash = '$user_password'";
It needs to be $user_username:$user_password
I hope you can help me :)
If what you have stored in the database is an SHA1 checksum, then that's what you will need to compare.
The details are pretty sketchy.
Assuming that the row was saved into the database as
INSERT INTO `account` (`username`, `sha_pass_hash`, ...
VALUES ('Meko', SHA1('Meko:1234'), ...
Then to check for the existence of that row, given:
$user_username = 'Meko' ;
$user_password = '1234' ;
if those are the values you want to pass into the database query, then
$sql = 'SELECT ...
FROM account a
WHERE a.username = ?
AND a.sha_pass_hash = SHA1( CONCAT( ? ,':', ? )';
$sth = $dbh->prepare($sql);
$sth->bindValue(1,$user_username, PDO::PARAM_STR);
$sth->bindValue(2,$user_username, PDO::PARAM_STR);
$sth->bindValue(3,$user_password, PDO::PARAM_STR);
$sth->execute();
if( $row = $sth->fetch(PDO::FETCH_ASSOC) ) {
// matching row found
} else {
// no matching row found
}
$sth->closeCursor();
If you didn't use the MySQL SHA1 function and used some other function to calculcate the hash, then use that same function when you do the check.
That is, if the row was inserted by a statement of a form more like
INSERT INTO account (username, sha_pass_hash, ... )
VALUES ('Meko','7c4d046a92c441c426ce86f15fa9ecd1fc1fd5f1', ... )
Then to check for the existence of that row, given:
$user_username = 'Meko' ;
$user_password = '1234' ;
Then your query to check for the existence of the row would be something like this:
$sql = 'SELECT ...
FROM account a
WHERE a.username = ?
AND a.sha_pass_hash = ?';
calculate the password hash, the same way as when it was originally done
$user_sha_hash = sha1( $user_username . ':' . $user_password) ;
And prepare and execute the query, passing in the SHA checksum string
$sth = $dbh->prepare($sql);
$sth->bindValue(1, $user_username, PDO::PARAM_STR);
$sth->bindValue(2, $user_sha_hash, PDO::PARAM_STR);
$sth->execute();
if( $row = $sth->fetch(PDO::FETCH_ASSOC) ) {
//
} else {
//
)
$sth->closeCursor();
I think you on php ?
$username = 'Meko';
$user_password = '1234';
$altered_pass = $user_username.':'.$user_password;
if($stmt = mysqli_prepare($con,"select * from account where username = ? and sha_pass_hash = ?") ){
mysqli_stmt_bind_param($stmt,'ss',$user_username,sha1($altered_pass));
mysqli_stmt_execute($stmt);
mysqli_stmt_store_result($stmt);
if(mysqli_stmt_num_rows($stmt)){
//"yup";
}
else{
//"nope";
}
mysqli_stmt_close($stmt);
}
mysqli_close($con);
You do not specify explicitly but assuming that your sha_pass_hash contains a hashed value of the following format: hash(username:password) then hash '$user_username' + ":" + '$user_password' first and then compare it to your password.
$search = $username.":".$password;
$query = "SELECT * FROM account WHERE password = ".$search;
IMPORTANT:
I very much hope you are preparing your statements and binding your parameters to prevent SQL injection attacks. If you are not, let me know and I can help you out in more detail so that your database is secure.
Also, I recommend that you create another table and fill it in with the values inside this account table. The previous answer is a quick fix so that your users can login meanwhile, but by no means should the previous table stay as it is.
Let me know if you need any more help :)
Okai, so I am trying to fetch multiple variables from the MySQL Database using PDO and I feel that I have to repeat myself alot in the code. Is there a neater way to write this or a more secure way?
Here is my code for the following example:
$username = $_SESSION['username'];
$db = new PDO('mysql:xxxxxxxx;dbname=xxxxxxxxxxxx', 'xxxxxx', 'xxxxxxx');
// FETCH name VARIABLE
$fetchname = $db->prepare("SELECT name FROM login WHERE username = :username");
$fetchname->bindParam(':username', $username, PDO::PARAM_STR, 40);
$fetchname->execute();
$myname = $fetchname->fetchColumn();
// FETCH age VARIABLE
$fetchage = $db->prepare("SELECT age FROM login WHERE username = :username");
$fetchage->bindParam(':username', $username, PDO::PARAM_STR, 40);
$fetchage->execute();
$myage = $fetchage->fetchColumn();
I wish to avoid having to repeat this FETCH for each variable from the same table...
Have you tried the fetchAll method
// FETCH name VARIABLE
$fetch = $db->prepare("SELECT name, age FROM login WHERE username = :username");
$fetch->bindParam(':username', $username, PDO::PARAM_STR, 40);
$fetch->execute();
$login = $fetch->fetchAll();
Just put all the fields you want into the same query.
$fetchAgeName = $db->prepare("SELECT name, age FROM login WHERE username = :username");
And you need fetchAll() instead of fetchColumn() as indicated by Igor.
Something like this perhaps?
$sth = $db->prepare("SELECT name, age, whatever FROM login WHERE username = :username");
$sth->bindParam(':username', $username, PDO::PARAM_STR, 40);
$sth->execute();
$login = $sth->fetchObject(); // fetches only the first row as an object
print "Hello {$login->name}, you are {$login->age} old. {$login->whatever}\n";
So I have a login system and I want to retrieve the first name of the person who is logged in. Here's my php:
function verify_Username_and_Pass($un, $pwd) {
$query = "SELECT `First Name`, Username, Password
FROM table
WHERE Username = :un AND Password = :pwd
LIMIT 1";
$stmt = $this->conn->prepare($query);
$stmt->bindParam(':un', $un);
$stmt->bindParam(':pwd', $pwd);
$stmt->execute();
if ($stmt->rowCount() > 0) {
// User exist
return true;
$stmt->close();
}
else {
// User doesn't exist
return false;
$stmt->close();
}
}
this is part of a class who has 1 private variable $conn. The login works perfectly but i just want to get the person's first name. How do I do that?
First off, NEVER grab the password from the database, that is just extremely bad practice.
Second, you only want to accept the user as correct if ONLY one row is returned.
lastly bindColumn is what you're looking for.
<?php
function verify_Username_and_Pass($un, $pwd) {
$query = "SELECT `First Name`, Username
FROM table
WHERE Username = :un AND Password = :pwd";
// Don't limit the query to only one, if there is a chance that you can
// return multiple rows, either your code is incorrect, bad data in the database, etc...
$stmt = $this->conn->prepare($query);
$stmt->bindParam(':un', $un);
$stmt->bindParam(':pwd', $pwd);
$stmt->execute();
// Only assume proper information if you ONLY return 1 row.
// Something is wrong if you return more than one row...
if ($stmt->rowCount() == 1) {
// User exist
$stmt->bindColumn('First Name', $firstName);
$stmt->bindColumn('Username', $username);
// You can now refer to the firstName and username variables.
return true;
$stmt->close();
} else {
// User doesn't exist
return false;
$stmt->close();
}
}
?>
That should work for you.
just change the query statement?
$query = "SELECT `First Name`
FROM table
WHERE Username = :un AND Password = :pwd
LIMIT 1";
if that throws errors, you would have to show more of what the class is doing to manage the db transaction
just change this line, to select only First Name in the query:
$query = "SELECT `First Name`, Username, Password
FROM table
WHERE Username = :un AND Password = :pwd
LIMIT 1";`
to
$query = "SELECT `First Name`
FROM table
WHERE Username = :un AND Password = :pwd
LIMIT 1";`
You need to bind the result as below
if ($stmt->rowCount() > 0) {
$stmt->bind_result($fname, $uname, $pwd);
$stmt->fetch()
echo $fname // here you get firsname
// either you can return this $fname or store into session variable for further
// User exist
return true;
$stmt->close();
}
else {
// User doesn't exist
return false;
$stmt->close();
}
In the section where you are returning true you could instead return the actual user data (and array with data will evaluate to true anyway).
Word of warning, you should use hashed passwords. Do not store the password y plain.
trying to convert all my old mysql_* operations into new and, from what i've heard, improved PDO, but this query wont seem to run successfully, I am trying to select all from the table PEOPLE where the username = $username (which has previously been declared $username = $_SESSION['username'];)
$query = "SELECT * FROM people WHERE username=?";
$stmt = $conn->prepare($query);
$stmt->bindParam(1, $username);
$stmt->execute();
$num_rows = $stmt->fetchColumn();
if ($num_rows == 1) {
// ...
}
THE WORKING CODE IS:
$query = "SELECT * FROM people
WHERE username=?";
$stmt = $conn->prepare($query);
$stmt->bindParam(1, $username);
$stmt->execute();
$num_rows = $stmt->fetchColumn();
$user = $stmt->fetchObject();
if ($user) {
//do something
}
$stmt->fetchColumn does not fetch the number of rows; in this case it will fetch the first column from the first row of the result set. Since that will not be equal to 1 generally your test will fail.
In this case there is also no real need to count the number of returned rows because you are expecting either one or zero (if the username does not exist). So you can simply do:
$stmt->execute();
$user = $stmt->fetchObject();
if (!$user) {
// not found
}
else {
echo "User $user->username found!";
}
The if(!$user) test works because if there is no row to fetch $user will be false (see the documentation for fetchObject).
$query = "SELECT * FROM people WHERE username = :username";
$stmt = $conn->prepare($query);
$stmt->bindParam(':username', $username);
$stmt->execute();
while ($row = $stmt->fetchObject()) {
// do stuff
}
Use PDOStatement::rowCount as the num_rows and PDOStatement::fetch(PDO::FETCH_ASSOC) as fetch_assoc equivalent.
You want
if ($stmt->num_rows == 1) {
instead.