This question already has answers here:
Can PHP PDO Statements accept the table or column name as parameter?
(8 answers)
Closed 9 years ago.
I want to fetch results from a MySQL database with PDO. The user should be able to order them by tablerow by which type (ascending or descending). This seems to only work when you hardcode it.
Does work:
$query = "SELECT * FROM ".$config->dbPrefix."content
WHERE cat_id = 2
ORDER BY id DESC
";
$query = $pdo->prepare($query);
$query->execute();
$result = $query->fetchAll();
Doesn't work:
$orderRow = 'id'; //from $_POST
$orderType = 'DESC' //from $_POST
$query = "SELECT * FROM ".$config->dbPrefix."content
WHERE cat_id = 2
ORDER BY :orderRow :orderType
";
$query = $pdo->prepare($query);
$query->bindValue(':orderRow', $orderRow);
$query->bindValue(':orderType', $orderType);
$query->execute();
$result = $query->fetchAll();
So my question is: what is the best way to do this and why isn't this implemented?
The best way I can think of is using a switch statement and writing the query for every different option which would have like 14 different available cases.
You can only provide placeholders for values in an SQL statement, not for column names or other kind of identifiers.
So instead of using bindValue, put the values in like you do for #config->dbPrefix, directly into the string. Make sure however that no SQL injection is possible.
Related
This question already has answers here:
Use an array in a mysqli prepared statement: `WHERE .. IN(..)` query [duplicate]
(8 answers)
How can I bind an array of strings with a mysqli prepared statement?
(7 answers)
Closed 11 months ago.
If I have this array:
$ids = [1, 34, 36];
How do I get data from a table from each of ID using this query:
$query = $DB->Prepare('SELECT name, address FROM tContacts WHERE id = ?');
I tried using:
foreach ($ids AS $val) {
$query = $DB->Prepare('SELECT name, address FROM tContacts WHERE id = ?');
$rs = $DB->Execute($query, array($val));
$i = 0;
foreach($rs as $rows)
{
$rs[$i++]=array(
'name' => $rows['name'],
'address' => $rows['address']
);
}
}
And when I tried to:
print_r($rs);
It only display the last row, not 3 rows as I intended.
You should use the IN function in the SQL condition.
Combine it with a php function to repeat the placeholders N times where N is the amount of the requested IDs in the array.
$ids = array(1,434,23);
$query = "SELECT name, address FROM tContacts WHERE id IN('".join("','",$ids)."')";
$stmt = $DB->Prepare($query);
Originally i've used str_repeat, but #pokeybit came up with an idea to use join which is much more comfortable.
In case the $ids array is being built based on a user's input or so, it would be better to use the query prepare mechanism and use placeholders.
$count = count($ids);
$query = "SELECT name, address FROM tContacts WHERE id IN(".str_repeat('?,',$count-1)."?)"; //would output: IN(?,?,?)
Then, use a loop to bind the relevant IDs from the array.
Note 1: Both of the ideas work, one is in case the developer sets the array, the other one use the advantages of preparing queries and binding which is a better solution in case the array's in dynamic/input-based. Therefore, I've wrote both of the solutions.
Note 2: See #JaredFarrish last comment regarding the advantages of prepared queries.
This question already has answers here:
PDO get the last ID inserted
(3 answers)
Closed 5 years ago.
I am trying to get the last id number of Database. But It's showing only 0.
I am learning PDO. Can anyone tell me how can I do it?
if($_SERVER['REQUEST_METHOD']=='POST'){
$sql = "SELECT * FROM tablename";
$stmt = $pdo->prepare($sql);
$stmt->execute();
$row = $stmt ->fetch();
$showid = $pdo->lastInsertId();
echo $showid;
}
lastInsertId will return the ID of a row that was inserted by the same connection. You can't use it outside of that context.
The easiest way to fetch the last ID would be to run something like,
SELECT max(id) FROM tablename
If you're using this in order to work out which ID should be inserted next, consider using an auto-increment column for your ID instead.
lastInsertId() works only after a INSERT query - since you're only doing a select, it will always return string(1) = 0
So either you perform this code after an INSERT statement, or you can do the following:
$stmt = $db->query("SELECT LAST_INSERT_ID()");
$lastId = $stmt->fetchColumn();
Refering here to: PDO get the last ID inserted
Visit this thread, you'll find my samplecode provided by Corbin and much more informations on this topic.
This question already has an answer here:
Can I use a PDO prepared statement to bind an identifier (a table or field name) or a syntax keyword?
(1 answer)
Closed 3 years ago.
Is it possible pass a column name as parameter in a prepared MySQL statement? Take the following example:
UPDATE Images
SET :placement = :imageURL
WHERE ID = :titleID;
PDO adds ' around each parameter, so the middle line above becomes:
SET 'Homepage' = '1.jpg'
Which MySQL doesn't like. Is there a way to include parameters for fieldnames in PDO statements and have them accepted?
Otherwise I guess I'll have to write several different PDO statements, depending on what's been chosen(?).
You would need to do something like this:
$column = 'someColumn';
$stmt = $db->prepare("UPDATE tableName SET {$column} = :columnValue WHERE ID = :recordId");
Parameterized placeholders are only for values.
I would suggest you read the comment #YourCommonSense posted on your question.
In situations such as this, I use a different sort of replacement parameters, like so:
$unitLabel = 'store_number';
$sql = 'select * from users where [unitLabel] = :unit and level = :level;';
$sql = str_replace('[unitLabel]', $unitLabel, $sql);
$params = array(
':unit' => 300,
':level' => 'admin',
);
$stmt = $dbh->prepare($sql);
$stmt->execute($params);
The prepared SQL query ends up being processed (more or less) as:
SELECT * FROM USERS WHERE store_number = 300 AND level = 'admin';
Which works for my situation. I hope this helps. :)
This question already has answers here:
PHP - Using PDO with IN clause array
(9 answers)
Closed 6 years ago.
$FSQL = $pdo->query('SELECT * FROM `connections` WHERE `uid`="'.$my_id.'" && `type`="1" ORDER by `id` DESC');
$myfriends = '`uid`="'.$my_id.'" ';
while($po = $FSQL->fetch(PDO::FETCH_ASSOC)){
$myfriends .= ' || `uid`="'.$po['cid'].'"';
}
$dsk = $pdo->query("SELECT * FROM `posts` WHERE ".$myfriends." ORDER by `id` DESC LIMIT ".$limitCount);
I have been trying to create a nice post stream, and I finally got my code down. But it seems so inefficient if you have a large amount of connections (connections being anything from friends, pages, or events).
Could someone tell me if there is a better way to do this?
--by the way: this is working perfectly already, but I feel like i'll run into issues down the line
$FSQL = $pdo->query('SELECT * FROMconnectionsWHEREuid="'.$my_id.'" &&type="1" ORDER byidDESC');
This is vulnerable to SQL Injection. You should be using parameters and prepared statements. See the Documentation.
Worked Example
$sql = $pdo->prepare('SELECT * FROM `table` WHERE `uid`=:uid');
// Create the SQL statement, with the parameter prefixed by a ":".
$userID = "username";
// Grab the value you wish to bind to your parameter.
$sql->bindParam(':uid', $userID);
// Bind the values, using the bindParam method.
$sql->execute();
// Execute the statement with the parameters bound to the SQL query.
You don't want to use a subquery?
Something like this...
$dsk = $pdo->query(
"SELECT *
FROM `posts`
WHERE uid IN (
SELECT cid
FROM `connections`
WHERE `uid`="'.$my_id.'" && `type`="1"
)
ORDER BY `id` DESC LIMIT " . $limitCount);
And try not to use * when you don't need all fields.
This question already has answers here:
How do I create a PDO parameterized query with a LIKE statement?
(9 answers)
Closed 4 months ago.
I've read multiple examples on how these queries should be written but I'm struggling to get this specific like to run when using bindParam
Would this be the correct way to match usernames that begin with a?
$term = "a";
$term = "'$term%'";
$sql = "SELECT username
FROM `user`
WHERE username LIKE :term
LIMIT 10";
$core = Connect::getInstance();
$stmt = $core->dbh->prepare($sql);
$stmt->bindParam(':term', $term, PDO::PARAM_STR);
$stmt->execute();
$data = $stmt->fetchAll();
No, you don't need the inner single quotes so just $term = "$term%";
The statement you're running now would try to match 'a%' instead of a%
bindParam will make sure that all string data is automatically properly quoted when given to the SQL statement.
You can use bindValue , suppose you are having a $query = "search string"
$stmt->bindValue(':term', $query.'%'); // this will do like search for "search term XXXXX"
similarly
$stmt->bindValue(':term', '%'.$query.'%');
or
$stmt->bindValue(':term', '%'.$query);