1

There are similar questions here and some rather complex answers. I don't believe it should be that complicated. Perhaps it is. I am new to PDO. I have an array of key-value pairs. I need to update a record with those values. Is there a more intelligent way to do this?

$sql = "UPDATE Table SET ? = ? WHERE ID = ?";
$stmt = $pdo->prepare($sql);
foreach($QueryString as $Key=>$Value)
{
    $stmt->execute($Key, $Value, $RecordID);
}
RationalRabbit
  • 1,037
  • 13
  • 20

1 Answers1

3

You can't bind a value to a column name, so your current code won't work at all. It would also be more efficient to form that query to make all the updates at once, for example:

$sql = "UPDATE Table SET";
$v = 0;
foreach ($QueryString as $Key=>$Value) {
    if ($v++ > 0) $sql .= ',';
    $sql .= " `$Key` = ?";
}
$sql .= " WHERE ID = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute(array_merge(array_values($QueryString), array($RecordID)));

Note that this query is still vulnerable to injection if the keys of the $QueryString array come from an outside source. To avoid this issue, you should check that the columns actually exist, either using a manually specified whitelist e.g.

$colnames = ['col1', 'col2', 'col3'];
foreach ($QueryString as $Key=>$Value) {
    if (!in_array($Key, $colnames)) {
        // abort
    }
    if ($v++ > 0) $sql .= ',';
    $sql .= " `$Key` = ?";
}

or by getting the list of the column names from the information_schema.columns table as described in this question and using the result of that query as your whitelist.

Your Common Sense
  • 156,878
  • 40
  • 214
  • 345
Nick
  • 138,499
  • 22
  • 57
  • 95