Как вставить массив в MySQL, используя PDO и bindParam? - PullRequest
2 голосов
/ 25 марта 2012

Я использую следующий код. Код работает, но я хочу изменить его, чтобы он использовал bindparam

try {
    $dbh = new PDO("mysql:host=$hostname;dbname=$dbname", $username, $password);
$stqid=array();

    for ($i=0; $i<$array_count; $i++){
    $stqid[$i][0]=$lastInsertValue;
    $stqid[$i][1]=$qid[$i][0];
    $stqid[$i][2]=$qid[$i][1];
    }

$values = array();
    foreach ($stqid as $rowValues) {
        foreach ($rowValues as $key => $rowValue) {
        $rowValues[$key] = $rowValues[$key];  
        }

    $values[] = "(" . implode(', ', $rowValues) . ")";
    }

$count = $dbh->exec("INSERT INTO qresults(instance, qid, result) VALUES  ".implode (', ', $values)); 
$dbh = null;
}
catch(PDOException $e){
    echo $e->getMessage();
}

Я заменил следующее

$count = $dbh->exec("INSERT INTO qresults(instance, qid, result) VALUES  ".implode (', ', $values)); 

с

$sql = "INSERT INTO qresults (instance, qid, result) VALUES (:an_array)";
$stmt = $dbh->prepare($sql);
$stmt->bindParam(':an_array', implode(',', $values),PDO::PARAM_STR);
$stmt->execute();

но вставка больше не работает (хотя я не получил сообщений об ошибках).

ВОПРОС: Что я делаю не так? Как я могу переписать код для использования bindParam?

1 Ответ

3 голосов
/ 25 марта 2012

Вы пытаетесь создать оператор и связать параметр.

Оператор хорош, потому что он потенциально сводит на нет любой вид SQL-инъекции.И делает это, удаляя концепцию запроса, который рассматривается только как строка.SQL-запрос рассматривается в виде строки со списком параметров и связанными данными в виде связанных переменных.Таким образом, запрос - это не только текст, но и текст + данные.

Я имею в виду:

Этот простой запрос:

SELECT * FROM A WHERE val="$param"

Это небезопасно, поскольку запрос является толькорассматривается как строка.И если $ param не проверено, это дыра в SQLi.

Но когда вы создаете оператор, ваш запрос выглядит так:

SELECT * FROM A WHERE val=:param

Затем вы используете bindparam для указания значения a: param,Это означает, что значение не добавляется в строку запроса, но запрос уже проанализирован и данные предоставлены.

В вашем случае вы привязываете к параметру: массив развернутый массив (я предполагаю, что «данные1»), "data2" и т. д.).Это всего один параметр со значением в виде строки («data1, data2, data3 ...»), поэтому он приведет только к одной вставке, а не к нескольким вставкам.

Вы можете изменить генерацию оператора с помощьюгенерация запроса с достаточным количеством параметров для обработки вашего массива

$sql = "INSERT INTO qresults (instance, qid, result) VALUES ( :val0, :val1, :val2, ...)";

Затем зациклите массив и вызовите метод bindparam для каждого параметра.

$count = 0;
foreach($values as $val)
{
   $stmt->bindParam(":val$count", $val,PDO::PARAM_STR);
   $count++;

}

Это будет работать.

Редактировать : Это решение показывает, как оно работает для одномерного массива, но может быть легко расширено для вашей проблемы путем настройки запроса оператора и изменения цикла bindparam.

Ваше утверждениедолжно выглядеть так:

$sql = "INSERT INTO qresults (instance, qid, result) VALUES (:val0, :val1, :val2) , (:val3, :val4, :val5), ...";

Вам просто нужно посчитать количество элементов в вашем базовом массиве.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...