PHP - безопасный PDO подготовил оператор с неизвестным количеством параметров

0

* Я видел вопрос об этой теме для случаев 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 ;

Как я могу это сделать? У меня нет определенной таблицы, в которой я хочу использовать эту функцию, а тем более разумного списка допустимых столбцов для проверки. Как создать оболочку, которая будет работать с разными значениями аргументов?

  • 2
    Вы пробовали любой из ответов здесь? stackoverflow.com/questions/12344741/… - выглядит многообещающе
  • 0
    Почти @Drew Этот ответ: stackoverflow.com/a/23298742/1194525
Показать ещё 4 комментария
Теги:
pdo

1 ответ

2
Лучший ответ

Для таких проблем лучше было бы создавать решения для построения 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

  • 0
    Я пытался сделать что-то подобное, но ваше решение более элегантно. Спасибо за ответ. Мой вопрос заключается в том, разве это не ставит под угрозу безопасность этого PDO, потому что переменная $ key не будет экранирована? Конечно, технически это должно исходить от разработчика, поэтому ему следует доверять, но я вроде бы предполагал, что все должно быть в безопасности. Если только мы не избежим этого вручную. Звучит забавно не доверять своему собственному коду, но что, если это, например, прототип интерфейса?
  • 1
    @DwarfVader просто убедитесь, что он исходит от разработчика или, скорее, из кода. Взятие ключей из списка, предопределенного в коде, считается достаточно безопасным. хотя вы все еще можете форматировать идентификаторы. В случае, когда ключи по существу определены пользователем, например, условное ОБНОВЛЕНИЕ или ГДЕ, просто отфильтруйте их, опять же, по заранее определенному и жестко закодированному списку
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню