Объединенный оператор обновления в один

Можно ли использовать подготовленный оператор PDO для привязки идентификатора (имя таблицы или поля) или ключевое слово синтаксиса?

К сожалению, подготовленный оператор может представлять только литерал данных. Итак, очень распространенная ошибка - это такой запрос:

$opt = "id";
$sql = "SELECT :option FROM t WHERE id=?";
$stm  = $pdo->prepare($sql);
$stm->execute(array($opt));
$data = $stm->fetchAll();

Зависит от настроек PDO, этот запрос будет вызван как ошибкой (в случае использования реальных подготовленных операторов), так и буквальной строкой 'id' в наборе полей (в случае эмулированных подготавливаний).

Итак, разработчик должен сам позаботиться об идентификаторах - PDO не предлагает никакой помощи в этом вопросе.

Чтобы сделать динамический идентификатор безопасен, нужно следовать двум строгим правилам:

  • правильно отформатировать идентификатор
  • , чтобы проверить его на жестком запросе белого списка.

Чтобы отформатировать идентификатор, нужно применить эти 2 правила:

  • Ввести идентификатор в обратные метки.
  • Сбросить обратные выходы внутри, удвоив их.

После такого форматирования безопасно вставить переменную $ table в запрос. Таким образом, код будет выглядеть следующим образом:

$field = "`".str_replace("`","``",$field)."`";
$sql   = "SELECT * FROM t ORDER BY $field";

Однако, хотя такого форматирования было бы достаточно для таких случаев, как ORDER BY, для большинства других случаев существует возможность для различного рода инъекций: разрешение пользователь может выбрать таблицу или поле, которое они могут видеть, мы можем выявить некоторую конфиденциальную информацию, такую ​​как пароль или другие личные данные. Таким образом, всегда лучше проверять динамические идентификаторы на список допустимых значений. Вот краткий пример:

$allowed = array("name","price","qty");
$key     = array_search($_GET['field'], $allowed);
$field   = $allowed[$key];
$query   = "SELECT $field FROM t"; //value is safe

. Правила ключевых слов одинаковы, но, конечно, нет форматирования - таким образом, возможен только белый список и должен использоваться:

$dir = $_GET['dir'] == 'DESC' ? 'DESC' : 'ASC'; 
$sql = "SELECT * FROM t ORDER BY field $dir"; //value is safe

См. также примечание, внесенное пользователем в документации PHP: Пользовательская заметка о PDO :: quote

1
задан Messi 16 January 2019 в 16:50
поделиться