У меня большая форма с примерно 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();