Bạn đang cố gắng tạo một tuyên bố và ràng buộc một tham số.
Câu lệnh rất tuyệt vì nó có khả năng vô hiệu hóa bất kỳ loại SQL injection nào. Và nó thực hiện điều đó bằng cách loại bỏ khái niệm truy vấn chỉ được xem như một chuỗi. Truy vấn SQL được xem như một chuỗi với danh sách tham số và dữ liệu được liên kết dưới dạng các biến liên kết. Vì vậy, truy vấn không chỉ là văn bản mà còn là văn bản + dữ liệu.
Ý tôi là:
Truy vấn đơn giản này:
SELECT * FROM A WHERE val="$param"
Nó không an toàn vì truy vấn chỉ được xem như một chuỗi. Và nếu $ param không được chọn, nó là một lỗ hổng SQLi.
Nhưng khi tạo một câu lệnh, truy vấn của bạn sẽ trở thành:
SELECT * FROM A WHERE val=:param
Sau đó, bạn sử dụng bindparam để chỉ định giá trị a:param. Có nghĩa là giá trị không được nối vào chuỗi truy vấn, nhưng truy vấn đã được phân tích cú pháp và dữ liệu được cung cấp.
Trong trường hợp của bạn, bạn liên kết với param:array một mảng đã nổ (tôi giả sử là "data1", "data2", v.v.). Chỉ một tham số có giá trị là một chuỗi ("data1, data2, data3 ..."), vì vậy nó sẽ chỉ dẫn đến một lần chèn chứ không phải nhiều lần chèn.
Bạn có thể thay đổi cách tạo câu lệnh của mình bằng cách tạo một truy vấn có đủ tham số để xử lý mảng của bạn
$sql = "INSERT INTO qresults (instance, qid, result) VALUES ( :val0, :val1, :val2, ...)";
Sau đó lặp lại trên mảng của bạn và gọi phương thức bindparam cho từng tham số.
$count = 0;
foreach($values as $val)
{
$stmt->bindParam(":val$count", $val,PDO::PARAM_STR);
$count++;
}
Điều này sẽ hoạt động.
Chỉnh sửa :Giải pháp này cho thấy cách nó hoạt động đối với mảng một chiều, nhưng có thể dễ dàng mở rộng cho vấn đề của bạn bằng cách điều chỉnh việc tạo truy vấn câu lệnh và sửa đổi vòng lặp bindparam.
Tuyên bố của bạn sẽ giống như sau:
$sql = "INSERT INTO qresults (instance, qid, result) VALUES (:val0, :val1, :val2) , (:val3, :val4, :val5), ...";
Bạn chỉ cần đếm số phần tử trong mảng cơ sở của mình.