* Я видел вопрос об этой теме для случаев mysqli или fringe для PDO, но не нашел этого конкретного вопроса (который меня удивил, но, может быть, я не знаю, как искать)
Прежде чем пытаться использовать PDO, я использовал простые незащищенные запросы. Моя функция подготовки выглядела так:
static function prepareUpdate($table, array $arguments, array $filter) {
$argumentsList = self::associateArguments($arguments);
$filterList = self::associateArguments($filter);
$query = "UPDATE '$table' SET $argumentsList WHERE $filterList;";
return $query;
}
$ arguments и $ filter - это ассоциативные массивы: ['name' => 'John', 'occupation' => 'Carpenter']
для $ arguments, например, ['employeeId' => 518]
для фильтра. Скажем, $ table - это "рабочие". Через некоторые простые функции он становится:
argumentsList становится
'name' = 'John', 'occupation' = 'Carpenter'
filterList становится
'employeeId' = 518
Итак, финальная строка становится:
UPDATE 'workers' SET 'name' = 'John', 'occupation' = 'Carpenter' WHERE 'employeeId' = 518;
Мне это показалось достаточно простым. Затем я попытался использовать аналогичную логику в отчетах о подготовке PDO. Но я столкнулся с бедой. Может быть, потому, что я не понимаю намеченной философии? Или просто технические вопросы.
PDO необходимо использовать метод bindValue(), и после того, как prepare() будет защищен от инъекций, если я правильно понимаю. И я должен использовать заполнители (: имя,: занятие и т.д.).
Вопрос в том, как мне это сделать, если я не знаю, какие столбцы я буду искать или даже сколько?
Большинство примеров, которые я вижу, включают очень предопределенный оператор: UPDATE tableX SET 'name' =: name WHERE 'id' =: id - или что-то в этом направлении.
Так что, если я хочу использовать переменное количество параметров? Мое понимание состоит в том, что я могу только заменить один: placeholder одним свойством, не более (следовательно, почему цитаты не нужны), поэтому я не могу точно написать что-то вроде:
UPDATE :table SET :allParametersHere ;
Как я могу это сделать? У меня нет определенной таблицы, в которой я хочу использовать эту функцию, а тем более разумного списка допустимых столбцов для проверки. Как создать оболочку, которая будет работать с разными значениями аргументов?
Для таких проблем лучше было бы создавать решения для построения database query builder
к database query builder
.
Возвращаясь к вопросу: вы знаете количество параметров, поэтому вы можете создать шаблон запроса.
<?php
$wq = $pq = [];
$allowed_keys = ['name', 'occupation', '...'];
foreach ($arguments AS $key => $value) {
if(in_array($key, $allowed_keys))
$pq[] = "$key = :$key" ;
else throw new Exception('Go away hacker!');
}
foreach ($filter AS $key => $value)
if(in_array($key, $allowed_keys))
$wq[] = "$key = :$key" ;
$q = "UPDATE $table SET ". join(', ', $pq);
if(!empty($wq))
$q .= 'WHERE '. join(' AND ', $wq);
В результатах вы получаете шаблон запроса, например:
UPDATE workers SET name = :name, occupation = :occupation WHERE employeeId = :employeeId;
Такая складка разрешена (если у вас есть "безопасные" ключи к этим таблицам)
$allowed_keys
или лучше $allowed_column_names