我正在使用PDO在具有10个输入字段的表单上插入来自用户的MySQL DB输入。我通过这样做来创建一个包含$_POST
值的数值数组:
foreach ($_POST as $key => $val)
{
//testInput() sanitizes the input
$postArray[] = testInput($val);
}
通过在线浏览的所有示例和答案以及使用PDO插入数据的SO,他们做了类似的事情(https://stackoverflow.com/a/767520/3040381):
$db = new PDO("...");
$statement = $db->prepare("insert into some_other_table (some_id) values (:some_id)");
$statement->execute(array(':some_id' => $row['id']));
我遇到的问题是,我有近10个用户输入要插入到我的数据库中。使用上面的方法,我必须做这样的事情:
$statement->execute(array(':id1' => $row['id'], ':id2' => $row['id2'], ':id3' => $row['id3'], ........':id10' => $row['id10'], ':id11' => $row['id11']));
这很多打字,让我想知道我是否正确地进行了打字,但是我没有看到任何其他方式在线使用PDO进行大规模INSERT。
我简化了这个:
//ConnectDB() is a method in another file that returns a PDO object
$dbHandle = ConnectDB();
/**
* Gets the columns of a MySQL table
* @param {String} $tableName is the name of the table
* @param {Object} $handle is the PDO object
* @return {array} returns a numeric array containing column names
*/
function getColumnNames($tableName, $handle) {
$query = $handle->prepare("SHOW COLUMNS FROM $tableName");
$query->execute();
$table_fields = $query->fetchAll(PDO::FETCH_COLUMN);
return $table_fields;
}
/**
* Builds an INSERT query using named placeholders
* @param {String} $tableName is the name of the table to be inserted
* @param {Object} $handle is the PDO object
* @return {String} returns a INSERT query
*/
function getColumnStrings($tableName, $handle) {
$columnArray = getColumnNames($tableName, $handle);
$size = sizeof($columnArray);
$sql = "(";
for($i = 0; $i < $size; $i++) {
$sql .= $columnArray[$i] . ",";
}
$sql = rtrim($sql, ",");
$sql .= ")";
$values = "VALUES (";
for($i = 0; $i < $size; $i++) {
$values .= ":" . $columnArray[$i] . ",";
}
$values = rtrim($values, ",");
$values .= ")";
return "INSERT INTO " . $tableName . " ". $sql . " " . $values;
}
/**
* Builds an associative array to place inside query->execute()
* @param {array} $postArray numeric array containing $_POST values
* @param {Object} $handle is the PDO object
* @param {String} $tableName is the name of the table
* @return {array} returns an associative array with
* values to be replaced
*/
function buildArr($postArray, $handle, $tableName) {
$namesArray = getColumnNames($tableName, $handle);
$size = sizeof($namesArray);
$paramArray = [];
for($i = 0; $i < $size; $i++) {
$namesArray[$i] = ":" . $namesArray[$i];
}
for($i = 0; $i < $size; $i++) {
$paramArray[$namesArray[$i]] = $postArray[$i];
}
return $paramArray;
}
我将命名的占位符放在一个数值数组中,然后在包含$_POST
值的数组的同时循环遍历占位符数组,并创建一个新的关联数组放在$query->execute()
参数中。
我也可以,而不是创建一个新数组,做bindValue()
并绑定两个数组中的每个索引元素,我认为这将是另一种选择。我的方法是以正确的方式插入大量用户输入吗?
答案 0 :(得分:1)
您的示例是一种方法,但我将举例说明我将如何处理此问题,尤其是当您可能有大量输入时,而不是经常需要更新SQL查询或数据库添加,删除或重新排序输入,或者不需要在接口和数据库之间创建不必要的依赖。
假设我们已经执行了任何我们想要进行的检查,我们知道要插入数组中的任何值,我会按照以下方式执行:
<?php
//This array gives us a way to match our incoming data to where it needs to be stored.
$lookup = array( 'form1' => 'id1', [...]);
$columns_params = array();
$params_values = array();
foreach($lookup as $form_key => $column_key) {
$param_key = ':'.$column_key;
$columns_params[$column_key] = $param_key;
$params_values[$param_key] = $_POST[$form_key];
}
$insert_statement = sprintf('insert into some_other_table (%s) VALUES (%s)', implode(',',array_keys($columns_params)), implode(',',array_values($columns_params)));
$statement = $db->prepare($insert_statement);
array_map(function($param, $value) use (&$statement) {
$statemnt->bindParam($param, $value);
}, $params_values);
$statement->execute();