Вставка большого количества переменных в таблицу с использованием PDO

У меня большая форма с примерно 25 полями ввода.

Я пытаюсь вставить их в таблицу и единственный способ, которым я знаю, как использовать следующее …

$count = $dbh->exec("INSERT INTO directory(field1, field2) VALUES (':value1', ':value2')"); 

Поскольку у меня так много пост-переменных, есть ли лучший способ сделать это, чем набирать всех и каждого в мой запрос?

Вы можете создавать инструкции INSERT динамически, но вы должны быть осторожны в ограничении полей POST. Не доверяйте запросу содержит только действительные столбцы.

Также разделите идентификаторы таблиц и столбцов. По умолчанию MySQL использует обратный тик как разделитель идентификатора.

 function execInsert($pdo, $table, $_POST) { // get a list of columns in $table, either by hard-coding them per table, // or by querying DESC or INFORMATION_SCHEMA $real_columns = array('col1', 'col2', 'col3'); $fields = array_intersect_key($_POST, array_flip($real_columns)); if (!$fields) { // no POST fields match the real columns return false; } $columns = array_map(function($col) { return "`".$col."`"; }, array_keys($fields)); $holders = array_map(function($col) { return ":".$col; }, array_keys($fields)); $values = $fields; $sql = "INSERT INTO `$table` (" . join(",", $columns) . " VALUES (" . join(",", $holders) . ")"; if (($stmt = $pdo->prepare($sql)) === false) { die(print_r($pdo->errorInfo(), true)); } if (($retval = $stmt->execute($values)) === false) { die (print_r($stmt->errorInfo(), true)); } return $retval; } 

Динамические подготовленные запросы

Динамический динамический запрос можно построить из массива $ _POST:

Но НИКОГДА не доверяйте пользовательскому вводу, что означает, что вы не можете доверять тому, что данные в $ _POST будут содержать допустимые имена столбцов.

1. Санитировать почтовые данные

Вы можете определить массив имен столбцов whitelisted $whitelist = array('field1', 'field2', ...) , а затем использовать:

 $data = array_intersect_key($_POST, array_flip($whitelist)); 

найти перекресток между столбцами белого списка и вашим массивом $ _POST. (Спасибо @BillKarwin)

2. Постройте запрос

 private function buildInsertSql($data, $table) { $columns = ""; $holders = ""; foreach ($data as $column => $value) { $columns .= ($columns == "") ? "" : ", "; $columns .= $column; $holders .= ($holders == "") ? "" : ", "; $holders .= ":$column"; } $sql = "INSERT INTO $table ($columns) VALUES ($holders)"; return $sql; } 

Это даст вам инструкцию SQL формы:

 $sql = INSERT INTO directory (field1, field2) VALUES (:field1, :field2) 

и подготовить заявление:

 $stmt = $dbh->prepare($sql); 

3. Параметры привязки

Затем вы можете динамически привязывать параметры к заполнителям:

 foreach ($data as $placeholder => $value) { $stmt->bindValue(":$placeholder", $value); } 

и выполните его:

 $stmt->execute(); 

Немного более продвинутый …

  • Взгляните на эту ссылку. Связывание с тем же заполнителем. Сведения о том, как сделать динамически подготовленный отчет более надежным.
  • Взгляните на эту ссылку: Bind Params Inside Loop. Предостережение относительно привязки параметров к значениям в цикле.