我正在使用以下代码。该代码有效,但我想更改它以便它使用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?
最佳答案
您正在尝试创建一个语句并绑定(bind)一个参数。
语句很棒,因为它有可能使任何类型的 SQL 注入(inject)无效。它通过消除查询仅被视为字符串的概念来实现这一点。 SQL 查询被视为带有参数列表的字符串和作为绑定(bind)变量的关联数据。 所以查询的不仅仅是文本,而是文本+数据。
我的意思是:
这个简单的查询:
SELECT * FROM A WHERE val="$param"
这是不安全的,因为查询仅被视为字符串。如果 $param 没有被检查,那么它就是一个 SQLi 漏洞。
但是当创建语句时,您的查询变为:
SELECT * FROM A WHERE val=:param
然后使用bindparam指定值a:param。这意味着该值不会附加到查询字符串中,但查询已被解析并提供了数据。
在你的例子中,你将一个内爆数组绑定(bind)到参数:array(我假设“data1”,“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++;
}
这会起作用。
编辑:此解决方案展示了它如何适用于一维数组,但可以通过调整语句查询生成并修改绑定(bind)参数循环轻松扩展到您的问题。
您的声明应如下所示:
$sql = "INSERT INTO qresults (instance, qid, result) VALUES (:val0, :val1, :val2) , (:val3, :val4, :val5), ...";
您只需计算基本数组中元素的数量即可。
关于mysql - 如何使用PDO和bindParam将数组插入mysql?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9858073/