Storing a value taken from db in a variable - php

I'm using PDO for the connection to my database. This is the code I'm using:
<?php
session_start();
if (ValidarCreacionUsuario($_POST)) {
if (ValidarNoEmpty($_POST)) {
$connection = new PDO('mysql:host=localhost;dbname=dbname', "dbuser", "dbpass");
$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();
And then, I want to catch the value of the 'sex' column and the value of the 'id' column in my database, so, I think I have to use the fetchAll() or something like this, but I don't know how to use it or if I have to use it.
So, what do I have to use?
Thanks.

something like this will show you what is available to you to use in an associative array (key and value)
$sql = "SELECT * FROM users... etc";
$stmt = $dbh->query($sql);
$result = $stmt->fetch(PDO::FETCH_ASSOC);
/*** loop over the object directly ***/
foreach($result as $key=>$val)
{
echo $key.' - '.$val.'<br />';
}

Related

No data returned with PDO

Here's the relevant piece of my PHP code:
$dbh = new PDO("mysql:host=$hostname;dbname=$database", $username, $password);
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
//get values from AJAX
$whereCategory = isset($_GET['cat_code'])? "{$_GET['cat_code']}" : '';
$sortvalue = isset($_GET['sortvalue'])? "{$_GET['sortvalue']}" : '';
$sortorder = isset($_GET['sortorder'])? "{$_GET['sortorder']}" : '';
$sql = "select * from {$table} where cat_code = ':cat_code' order by ':sortvalue' ':sortorder';";
$stmt2 = $dbh->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY) );
$stmt2->execute(array(':cat_code' => $whereCategory,':sortvalue' => $sortvalue, ':sortorder' => $sortorder));
$result = $dbh->query($sql)->fetchAll(PDO::FETCH_ASSOC);
header('Content-type: application/json');
echo json_encode($result);
If I var_dump the variables $where_category,$sortorder, and $sortvalue, they are all what I expect and the correct data that would need to be passed in the query. I've tried the query directly without PDO just substituting in the correct variables and I get back what I want, but apparently I'm not sending the variables correctly with my PDO methods (such as they are).
I'm getting no errors back, but no data returned either.
Any suggestions?
First off, named placeholders doesn't need to be quoted, so ditch those.
Secondly, you cannot bind identifiers (table/columns/DESC/ASC) You could only whitelist those.
Third, don't mix ->query() and ->execute(). Use ->execute() alone:
header('Content-type: application/json');
$dbh = new PDO("mysql:host=$hostname;dbname=$database", $username, $password);
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
//get values from AJAX
if(isset($_GET['cat_code'], $_GET['sortvalue'], $_GET['sortorder'])) {
$whereCategory = $_GET['cat_code'];
$sortvalue = $_GET['sortvalue'];
$sortorder = $_GET['sortorder'];
// super simple filtering
$default_tables = array('table1', 'table2', 'table3');
$default_columns = array('column1', 'column2', 'column3');
in_array(needle, haystack)
if(
in_array($table, $default_tables) &&
in_array($sortvalue, $default_columns) &&
in_array($sortorder, array('ASC', 'DESC'))
) {
// good to go
$sql = "SELECT * FROM $table where cat_code = :cat_code ORDER BY $sortvalue $sortorder";
$stmt2 = $dbh->prepare($sql);
$stmt2->execute(array(':cat_code' => $whereCategory));
echo json_encode($stmt2->fetchAll(PDO::FETCH_ASSOC));
} else {
// did not satisfy condition
}
}
Sidenote: Those default tables and columns are just examples, you'll need to populate and correspond it into yours. You could create your own method/function which creates a map with tables with their corresponding columns if you really want to be sure of it.
Change this -
$result = $dbh->query($sql)->fetchAll(PDO::FETCH_ASSOC);
to this -
$result = $stmt2->fetchAll(PDO::FETCH_ASSOC);
You're trying to run the query again when all you need to do is grab the results.
The query you are running is against a prepared statement which is incorrect, removing the query and assigning the result from the execute statement will work. There's also quite a few other problems in your php. Also using the input directly from the user such as the table (which appears to be undefined in this code snippet), sort order and sort value leaves you open to sql injection.
$dbh = new PDO("mysql:host=$hostname;dbname=$database", $username, $password);
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
//get values from AJAX
$whereCategory = isset($_GET['cat_code'])? $_GET['cat_code'] : '';
$sortvalue = isset($_GET['sortvalue'])? $_GET['sortvalue'] : '';
$sortorder = isset($_GET['sortorder'])? $_GET['sortorder'] : '';
/** you cannot use prepared statements for doing the order by */
$sql = "select * from $table where cat_code = :cat_code order by $sortvalue $sortorder;";
$stmt2 = $dbh->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY) );
$query = $stmt2->execute(['cat_code' => $whereCategory]);
/** below line isn't needed because above on deals with it */
//$dbh->query($sql)->fetchAll(PDO::FETCH_ASSOC);
$result = $query->fetchAll();
header('Content-type: application/json');
echo json_encode($result);
try without quotes:
$sql = "select * from {$table} where cat_code = :cat_code order by :sortvalue :sortorder;";
Use Like this
$result = $stmt2->fetchAll(PDO::FETCH_ASSOC);

DELETE multiple rows in PDO

I'm a rookie in PDO and I've done some search about the issue I'm facing and I wasn't able to find any answers about it. As you can see below, I have this function:
function deleteInfo($id){
$pdo = connPDO();
$deleteInfo = $pdo -> prepare("DELETE FROM game_locais_zumbis WHERE id_zumbi IN (:id)");
$deleteInfo -> bindValue(":id", $id, PDO::PARAM_STR);
$deleteInfo -> execute();
$pdo = null;
}
After that, I have the following code:
while($row = $listInfo -> fetch(PDO::FETCH_ASSOC)){
$ids[] = $row['ids'];
}
$ids = implode(',', $ids);
deleteInfo($ids);
When I echo my $ids, I get:
1,2,3,4,5
But the DELETE function is not deleting all those five rows in my db but only the first one, like "1". When I run that exactly same DELETE function in my db, replacing the ":id" with "1,2,3,4,5", it does work! Does anybody know what's my mistake here? I appreciate any help.
I would do this:
$query = "DELETE FROM game_locais_zumbis WHERE id_zumbi in (".str_repeat("?,", count($ids) - 1)."?)";
$stmt = $conn->prepare($query);
$stmt->execute($ids);
Unfortunately you can't bind an array of elements with prepared statements. You will have to build them in the query directly.
function deleteInfo($ids)
{
$pdo = connPDO();
if (!is_array($ids))
$ids = array($ids); // if it is just one id not in an array, put it in an array so the rest of the code work for all cases
$ids = array_map([$pdo, 'quote'], $ids); // filter elements for SQL injection
$pdo->exec('DELETE FROM game_locais_zumbis WHERE id_zumbi IN (' . implode(', ', $ids) . ')');
}
Remember to pass the array to deleteInfo() instead of imploding it into a string.
This is how i have done it and it worked. I created an array and looped through it.
<?php
// set a database connection
$host = "localhost";
$user ="root";
$password = "";
$db = "pdopost";
//Set a DSN
$dsn = 'mysql:host ='.$host . ';dbname='.$db;
// Create a PDO instance
$pdo = new PDO ($dsn, $user, $password);
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
$ids=['6', '7'];
foreach($ids as $id){
$sql = "DELETE FROM posts WHERE id = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([$id]);
}
echo 'Deleted in the database';
?>

PDO select query return only the first row

I am new at PDO. I was trying to retrieve data from the database by using a search keyword,
but I only get the first row in which the keyword is match. It doesn't return other rows.
Here is my code::
<?php
$dsn = 'mysql:host=localhost;dbname=cois';
$user = 'root';
$password = '';
$pdo = new PDO($dsn, $user, $password);
$filmName = "shaban";
$sql= "SELECT * FROM staff_info WHERE fname = :filmName";
$stmt = $pdo->prepare($sql);
$stmt->bindParam(':filmName', $filmName, PDO::PARAM_STR);
$stmt->execute();
$total = $stmt->rowCount();
while ($row = $stmt->fetchObject()) {
echo $row->surname.'</br>';
}
Currently it return only the first row.....it prints shekidere
How can i make it print both shekidere and kimweri
Any help?
Of course it stops always on the first row. You can use foreach instead of while and use an $arrayVariable[] = CurrentRow ; to fill it next by next.

Convert mysqli to pdo bind_all

here is my current code
function getUserDetails($username=NULL, $id=NULL) {
if($username!=NULL) {
$column = "user_name";
$data = $username;
}
elseif($id!=NULL) {
$column = "id";
$data = $id;
}
global $db;
$query = $db->prepare("SELECT id, username, permissions, forename, surname, password, email, courseid, choiceid, lastlogin, active FROM users WHERE $column = :column");
$query->bindParam(":column", $data);
$query->execute();
$query->bind_result ($id, $username, $permissions, $forename, $surname, $password, $email, $courseid, $choiceid, $lastlogin, $active);
while ($query->fetch()){
$row = array('id' => $id, 'userlevel' => $permissions, 'username' => $username, 'forename' => $forename, 'surname' => $surname, 'password' => $password, 'email' => $email, 'courseId' => $courseid, 'choiceId' => $choiceId, 'lastlogin' => $lastlogin, 'active'=> $active);
}
return ($row);
}
I have been trying to convert this to pdo, as I've found out bind_result doesn't work with pdo - could anyone help me as to what I should be doing?
I've read arround that I should be using fetch? But i'm getting really confused.
[edit]
ive tried this:
function getUserDetails($username=NULL,$id=NULL) {
if($username!=NULL) {
$column = "user_name";
$data = $username;
}
elseif($id!=NULL) {
$column = "id";
$data = $id;
}
global $db;
$query = $db->prepare("SELECT id, username, permissions, forename, surname, password, email, courseid, choiceid, lastlogin, active FROM users WHERE $column = :column");
$query->bindParam(":column", $data);
$query->execute();
$results = array();
while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
$results[] = $row;
}
return ($results);
}
is this a step in the right direction ?
[edit2]
updated my code to this:
function getUserDetails($username) {
global $db;
$query = $db->prepare("SELECT * FROM users WHERE username = :username");
$query->bindParam(":username", $username);
return $query->fetch(PDO::FETCH_ASSOC);
}
$username = 'uname';
$result = getUserDetails($username);
print_r($result);
however it prints nothing. the username definitely exists.
ive tried a test database with some dummy data
$data = '2';
$sth = $db->prepare("SELECT * FROM test WHERE id = :id");
$sth->bindParam(":id", $data);
$sth->execute();
$result = $sth->fetch(PDO::FETCH_ASSOC);
print_r($result);
im trying to figure out how i access what is in the printed array:
the array comes out as
Array ( [Id] => 2 [Name] => tom )
how do i (for example) do
$name = $result['name']; //line 67
when i try that code i get
Notice: Undefined index: name in <directory>\test.php on line 67
Figured it out!
function getUserDetails($username) {
global $db;
$sth = $db->prepare("SELECT id, username, permissions, forename, surname, password, email, courseid, choiceid, lastlogin, active FROM users WHERE username = :username");
$sth->bindParam(":username", $username);
$sth->execute();
$result = $sth->fetch(PDO::FETCH_ASSOC);
return $result;
}
$username = 'un';
$userdetails = getUserDetails($username);
echo $userdetails['forename'];
and it gives me the correct answer!
thanks for your help
YES!
It's great step in the right direction.
As you can see, mysqli is absolutely unusable with prepared statements, both in binding placeholders and returning results.
while PDO can solve your problem using dramatically less code.
You don't need useless bind with PDO at all - just get all results with fetchAll():
function getUserDetails($username=NULL,$id=NULL) {
if ($username) {
$column = "user_name";
$data = $username;
} elseif($id) {
$column = "id";
$data = $id;
} else {
return;
}
global $db;
$query = $db->prepare("SELECT * FROM users WHERE $column = ?");
$query->execute(array($data));
return $query->fetchAll();
}
But wait. Why do you want to return an array if it's users details?
It will add just useless dimension to the returned array.
For this very case make it
return $query->fetch();
instead of fetchAll().
But then you need many rows - use this latter method.
On other methods and useful connect options refer to the tag wiki

Print_r and foreach giving different results

I have a pdo function that fetches usernames and user ids from the database. When I run the function i get different results.
print_r gives
Array ( [ID] => 58 [username] => abdullatif )
and foreach gives me
5-5a-a
There is one row that matches the pdo query in the database.
public function getUserCredentials($userName, $password){
$this->db = new Dbpdo_Database();
$this->db->connect();
try{
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $dbh->prepare("SELECT
ID
FROM
administrators
WHERE
username = :username
AND
user_password = :password
LIMIT 1");
$stmt->bindParam(':username', $userName, PDO::PARAM_STR);
$stmt->bindParam(':password', $password, PDO::PARAM_STR);
}
$stmt->execute();
/*** fetch the results ***/
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
return $results;
/*** close the database connection ***/
//$dbh = null;
}
catch(PDOException $e){
echo $e->getMessage();
}
}
$results = $mydb->getUserCredentials($userName, $password);
foreach ($results as $row){
echo $row['ID'].'-'.$row['username'];
}
print_r($results);
Any hints as to whats wrong would be much appreciated. Thanks in advance.
Your $results array is one-dimensional - it has an ID and a username. Your foreach is looking for a two-dimensional array, with each row containing an ID and a username. Change it to:
foreach($results as $key => $value) {
echo $key . '-' . $value;
}
and you should get:
ID-58
username-abdullatif

Categories