Php 使用PDO和大量插入值的正确方法

Php 使用PDO和大量插入值的正确方法,php,mysql,post,pdo,Php,Mysql,Post,Pdo,我使用PDO在一个表单上插入来自用户的MySQL DB输入,表单上有10个输入字段。通过执行以下操作,我创建了一个包含$\u POST值的数字数组: foreach ($_POST as $key => $val) { //testInput() sanitizes the input $postArray[] = testInput($val); } 从我在线浏览的所有示例和答案中,使用PDO插入数据,它们可以执行如下操作(): 我遇到的问题是,我有将近10个用户输

我使用PDO在一个表单上插入来自用户的MySQL DB输入,表单上有10个输入字段。通过执行以下操作,我创建了一个包含
$\u POST
值的数字数组:

foreach ($_POST as $key => $val)
{
     //testInput() sanitizes the input
     $postArray[] = testInput($val);
}
从我在线浏览的所有示例和答案中,使用PDO插入数据,它们可以执行如下操作():

我遇到的问题是,我有将近10个用户输入要插入到我的数据库中。使用上述方法,我必须这样做:

$statement->execute(array(':id1' => $row['id'], ':id2' => $row['id2'], ':id3' => $row['id3'], ........':id10' => $row['id10'], ':id11' => $row['id11']));
这需要大量的输入,让我怀疑我是否做得正确,但我没有看到任何其他方法可以通过PDOs在线进行大规模插入

我把它简化了一点:

    //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;
}
//ConnectDB()是另一个文件中返回PDO对象的方法
$dbHandle=ConnectDB();
/**
*获取MySQL表的列
*@param{String}$tableName是表的名称
*@param{Object}$handle是PDO对象
*@return{array}返回包含列名的数字数组
*/
函数getColumnNames($tableName,$handle){
$query=$handle->prepare(“显示$tableName中的列”);
$query->execute();
$table_fields=$query->fetchAll(PDO::FETCH_列);
返回$table_字段;
}
/**
*使用命名占位符生成插入查询
*@param{String}$tableName是要插入的表的名称
*@param{Object}$handle是PDO对象
*@return{String}返回插入查询
*/
函数getColumnStrings($tableName,$handle){
$columnArray=getColumnNames($tableName,$handle);
$size=sizeof($columnArray);
$sql=“(”;
对于($i=0;$i<$size;$i++){
$sql.=$columnArray[$i]。“,”;
}
$sql=rtrim($sql,“,”);
$sql.=”;
$values=“values(”;
对于($i=0;$i<$size;$i++){
$values.=“:”$columnArray[$i]。“,”;
}
$values=rtrim($values,“,”);
$values.=”;
返回“插入到“$tableName.”“$sql.”“$values中”;
}
/**
*构建关联数组以放置在查询->执行()中
*@param{array}$postArray包含$\u POST值的数值数组
*@param{Object}$handle是PDO对象
*@param{String}$tableName是表的名称
*@return{array}返回具有
*要替换的值
*/
函数buildArr($postArray、$handle、$tableName){
$namesArray=getColumnNames($tableName,$handle);
$size=sizeof($namesArray);
$paramArray=[];
对于($i=0;$i<$size;$i++){
$namesArray[$i]=“:”$namesArray[$i];
}
对于($i=0;$i<$size;$i++){
$paramArray[$namesArray[$i]]=$postArray[$i];
}
返回$paramary;
}
我将命名的占位符放在一个数字数组中,然后与包含
$\u POST
值的数组同时循环遍历占位符数组,并创建一个新的关联数组,以放置在
$query->execute()
参数中


我还可以不创建新数组,而是执行
bindValue()
并绑定两个数组中的每个索引元素,我认为这是一种替代方法。我插入大量用户输入的方法正确吗?

您的示例就是一种方法,但我将给出我如何处理此问题的示例,特别是当您可能有大量输入时,无需在添加、删除时不断更新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();

有这么多的输入(为什么要把它放在一个表中呢!)您应该只使用未命名的参数(
)。这样你就可以单独传递一个值数组,而值的顺序才是最重要的;但是,如果您想保持这种方式,可以始终使用bindParam()执行循环。@versalle88与我建议的“执行bindValue()并同时绑定两个数组中的每个索引元素”类似,或者您可以提供一个示例吗please@Abdul是的,也差不多。您以类似的方式调用bindValue()和bindParam(),但PHP对它们的处理方式不同。然后我可以循环输入并在循环中生成查询,与输入名称/order/etc和数据库列名/order/etc保持分离。您可以部分地这样做,但它是动态出现的,在我看来这是不必要的开销,并将您的接口绑定到数据库。是的,在你发表评论后,我也在考虑同样的事情。我打算将我的HTML输入名称重命名为数据库列名。然后,在PHP端,在一个循环中,我将$_POST[columnName](因为列名和HTML名称是相同的,并且我已经有了一个将列名检索到数组的函数)绑定到命名参数。这使我不再担心顺序,同时也允许我在循环中构建查询。
<?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();