Próbujesz utworzyć oświadczenie i powiązać param.
Instrukcje są świetne, ponieważ potencjalnie unieważniają każdy rodzaj iniekcji SQL. I robi to, usuwając koncepcję zapytania, które jest postrzegane tylko jako ciąg. Zapytanie SQL jest postrzegane jako ciąg znaków z listą parametrów i powiązanymi danymi jako powiązane zmienne. Zapytanie to nie tylko tekst, ale tekst + dane.
Mam na myśli:
To proste zapytanie:
SELECT * FROM A WHERE val="$param"
Nie jest to bezpieczne, ponieważ zapytanie jest wyświetlane tylko jako ciąg. A jeśli $param nie jest zaznaczone, jest to dziura SQLi.
Ale kiedy tworzysz oświadczenie, twoje zapytanie staje się:
SELECT * FROM A WHERE val=:param
Następnie używasz bindparam do określenia wartości :param. Co oznacza, że wartość nie jest dołączona do ciągu zapytania, ale zapytanie jest już przeanalizowane i dane są dostarczone.
W twoim przypadku wiążesz z param :array implodowaną tablicę (zakładam "data1", "data2" itp.). Który jest tylko jednym parametrem z wartością w postaci ciągu ( "data1, data2, data3..." ), więc spowoduje to tylko jedną wstawkę, a nie wiele wstawień.
Możesz zmienić generowanie wyciągów, generując zapytanie z wystarczającą liczbą parametrów, aby obsłużyć twoją tablicę
$sql = "INSERT INTO qresults (instance, qid, result) VALUES ( :val0, :val1, :val2, ...)";
Następnie wykonaj pętlę w swojej tablicy i wywołaj metodę bindparam dla każdego parametru.
$count = 0;
foreach($values as $val)
{
$stmt->bindParam(":val$count", $val,PDO::PARAM_STR);
$count++;
}
To zadziała.
Edytuj :To rozwiązanie pokazuje, jak to działa w przypadku tablicy jednowymiarowej, ale można je łatwo rozszerzyć na swój problem, dostosowując generowanie zapytań i modyfikując pętlę bindparam.
Twoje oświadczenie powinno wyglądać tak:
$sql = "INSERT INTO qresults (instance, qid, result) VALUES (:val0, :val1, :val2) , (:val3, :val4, :val5), ...";
Musisz tylko policzyć liczbę elementów w swojej tablicy bazowej.