Best way to fetch multiple variables from MySQL Database using PDO - php

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";

Related

number of rows in database - prepared statements - 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();
}

can someone tell me how to count the select prepare statement returns?

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>";

Obtaining an specific db value

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.

This PDO statement is returning an integer instead of a string

In a class, I have some PDO:
$userFName = 'userFName';
include('dbconnect.php'); // Normally I'd store the db connect script outside of webroot
$pdo = new PDO("mysql:host=$db_host;dbname=$db_name;", $db_user, $db_password);
$stmt = $pdo->prepare('SELECT userFName FROM Users WHERE username = :uname AND password = :pword AND roleID = 1');
$stmt->bindParam(':uname', $this->user->username);
$stmt->bindParam(':pword', $this->user->password);
$stmt->bindColumn(4, $userFName, PDO::PARAM_STR);
$stmt->execute();
$familiar = $stmt->fetch(PDO::FETCH_BOUND);
$this->user->firstName = $familiar;
It's returning the ID in the first column instead of the VARCHAR contents in the 4th column. Any idea why?
When using PDO::FETCH_BOUND with fetch(), the method will not return a result record. Instead the value of the column should be available in the variable you have bound using $stmt->bindColumn() earlier.
So change your code to:
$stmt->bindColumn(1, $userFName, PDO::PARAM_STR);
$stmt->execute();
$stmt->fetch(PDO::FETCH_BOUND);
$this->user->firstName = $userFName; // <-- use the bound variable
However you won't need that bindColumn() call. You could simplify the code as this:
$stmt->execute();
$row = $stmt->fetch(); // uses PDO::FETCH_ASSOC by default
$this->user->firstName = $row['FName'];
There is too much code in your class. And one fault. To send a distinct query to get just one property from database, creating a distinct connection for this is a dead overkill.
Connection have to be moved away unconditionally and you must think of getting ALL user data with one query.
Proper code
function __construct($pdo) {
$this->pdo = $pdo;
// Normally you should include somewhere in a bootstrap file
// not in the application class
// and instantiate PDO in that bootstrap as well
// and only PASS already created instance to the class
}
function getUserFName() {
$sql = 'SELECT * FROM Users WHERE username = ? AND password = ? AND roleID = 1';
$stmt = $pdo->prepare($sql);
$stmt->execute(array($this->user->username,$this->user->password));
return $stmt->fetchColumn();
}

How can I properly use a PDO object for a parameterized SELECT query

I've tried following the PHP.net instructions for doing SELECT queries but I am not sure the best way to go about doing this.
I would like to use a parameterized SELECT query, if possible, to return the ID in a table where the name field matches the parameter. This should return one ID because it will be unique.
I would then like to use that ID for an INSERT into another table, so I will need to determine if it was successful or not.
I also read that you can prepare the queries for reuse but I wasn't sure how this helps.
You select data like this:
$db = new PDO("...");
$statement = $db->prepare("select id from some_table where name = :name");
$statement->execute(array(':name' => "Jimbo"));
$row = $statement->fetch(); // Use fetchAll() if you want all results, or just iterate over the statement, since it implements Iterator
You insert in the same way:
$statement = $db->prepare("insert into some_other_table (some_id) values (:some_id)");
$statement->execute(array(':some_id' => $row['id']));
I recommend that you configure PDO to throw exceptions upon error. You would then get a PDOException if any of the queries fail - No need to check explicitly. To turn on exceptions, call this just after you've created the $db object:
$db = new PDO("...");
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
I've been working with PDO lately and the answer above is completely right, but I just wanted to document that the following works as well.
$nametosearch = "Tobias";
$conn = new PDO("server", "username", "password");
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sth = $conn->prepare("SELECT `id` from `tablename` WHERE `name` = :name");
$sth->bindParam(':name', $nametosearch);
// Or sth->bindParam(':name', $_POST['namefromform']); depending on application
$sth->execute();
You can use the bindParam or bindValue methods to help prepare your statement.
It makes things more clear on first sight instead of doing $check->execute(array(':name' => $name)); Especially if you are binding multiple values/variables.
Check the clear, easy to read example below:
$q = $db->prepare("SELECT id FROM table WHERE forename = :forename and surname = :surname LIMIT 1");
$q->bindValue(':forename', 'Joe');
$q->bindValue(':surname', 'Bloggs');
$q->execute();
if ($q->rowCount() > 0){
$check = $q->fetch(PDO::FETCH_ASSOC);
$row_id = $check['id'];
// do something
}
If you are expecting multiple rows remove the LIMIT 1 and change the fetch method into fetchAll:
$q = $db->prepare("SELECT id FROM table WHERE forename = :forename and surname = :surname");// removed limit 1
$q->bindValue(':forename', 'Joe');
$q->bindValue(':surname', 'Bloggs');
$q->execute();
if ($q->rowCount() > 0){
$check = $q->fetchAll(PDO::FETCH_ASSOC);
//$check will now hold an array of returned rows.
//let's say we need the second result, i.e. index of 1
$row_id = $check[1]['id'];
// do something
}
A litle bit complete answer is here with all ready for use:
$sql = "SELECT `username` FROM `users` WHERE `id` = :id";
$q = $dbh->prepare($sql);
$q->execute(array(':id' => "4"));
$done= $q->fetch();
echo $done[0];
Here $dbh is PDO db connecter, and based on id from table users we've get the username using fetch();
I hope this help someone, Enjoy!
Method 1:USE PDO query method
$stmt = $db->query('SELECT id FROM Employee where name ="'.$name.'"');
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
Getting Row Count
$stmt = $db->query('SELECT id FROM Employee where name ="'.$name.'"');
$row_count = $stmt->rowCount();
echo $row_count.' rows selected';
Method 2: Statements With Parameters
$stmt = $db->prepare("SELECT id FROM Employee WHERE name=?");
$stmt->execute(array($name));
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
Method 3:Bind parameters
$stmt = $db->prepare("SELECT id FROM Employee WHERE name=?");
$stmt->bindValue(1, $name, PDO::PARAM_STR);
$stmt->execute();
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
**bind with named parameters**
$stmt = $db->prepare("SELECT id FROM Employee WHERE name=:name");
$stmt->bindValue(':name', $name, PDO::PARAM_STR);
$stmt->execute();
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
or
$stmt = $db->prepare("SELECT id FROM Employee WHERE name=:name");
$stmt->execute(array(':name' => $name));
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
Want to know more look at this link
if you are using inline coding in single page and not using oops than go with this full example, it will sure help
//connect to the db
$dbh = new PDO('mysql:host=localhost;dbname=mydb', dbuser, dbpw);
//build the query
$query="SELECT field1, field2
FROM ubertable
WHERE field1 > 6969";
//execute the query
$data = $dbh->query($query);
//convert result resource to array
$result = $data->fetchAll(PDO::FETCH_ASSOC);
//view the entire array (for testing)
print_r($result);
//display array elements
foreach($result as $output) {
echo output[field1] . " " . output[field1] . "<br />";
}

Categories