我有一个数组$ authors,其中包含一些我希望插入表中的数字。
我可以准备一个语句来为数组中的每个元素执行多次:
$stmt = $pdo->prepare('INSERT INTO authors (article_id, user_id) VALUES(?, ?)');
$stmt->bindParam(1, $article_id);
$stmt->bindParam($author);
foreach($authors as $author) {
$stmt->execute();
}
但是,我可以使用implode()
做一个技巧,只执行一次语句:
// here probably $authors = array_map('intval', $authors);
$stmt = $pdo->prepare(
'INSERT INTO authors (article_id, user_id)
VALUES ('.implode(', :article_id), (', $authors).', :article_id)');
$stmt->execute([':article_id' => $article_id]);
implode
之外没有循环)
在这种情况下哪种方法正确?
编辑:第二个查询的echo
给出了这个:
INSERT INTO authors (article_id, student_id)
VALUES (121, :article_id), (50, :article_id)
执行时没有错误。
答案 0 :(得分:1)
根据PDO的文档"除非启用仿真模式,否则不能在预准备语句中多次使用同名的命名参数标记。"。因此,仅此一点就会使你的内心发生内爆。解决方案不好。
话虽如此,我会回答这个理论。准备语句的要点是只编译一次查询,因此重复执行的速度更快。如此准备好的陈述应该用在你的第一个例子中:一个简单的"模板"查询,重复多次。
在第二个示例中,您创建了一个自定义查询,几乎不会重复(因为它基于$ authors数组的内容)。因此,在这种情况下准备好的语句完全没用,你有PREPARE的开销而没有重复执行的好处。 它不应该被使用。
扩展插入是一个非常有效的解决方案,并且是一个很好的解决方案,但使用普通查询(即exec()
),并确保使用quote()
来防止SQL注入!