【发布时间】:2015-07-13 08:23:48
【问题描述】:
我有一个表单,它接受一些姓名和电话号码,并将它们发布到 PHP 脚本,然后将这些值插入到 MySQL 表中。代码 (PHP) 非常简单,您可以在此处看到:
$sql = "INSERT INTO Contact_table (PHONE, NAME) VALUES ";
for ($i = 0; $i < $arr; ++$i){
$sql .= "('".$numbers[$i]."', '".$names[$i]."'),";
}
$sql = substr($sql, 0, -1)." ON DUPLICATE KEY UPDATE name = COALESCE(VALUES(name), name);";
$connect = dbconn(PROJHOST,PROJDB,PROJDBUSER,PROJDBPWD);
$query = $connect->query($sql);
$connect = NULL;
除了拒绝接受像 O'Hara 或 D'Souza 这样的任何名字之外,这很完美。我隐约知道 PDO 的准备好的声明在这种情况下有一些用处,但我无法让它发挥作用。我尝试的是这样的:
$query = $connect->prepare($sql);
$query->execute();
而不是这个:
$query = $connect->query($sql);
有什么提示吗?我错过了什么?
【问题讨论】:
-
您的代码不仅不适用于像 O'Hara 这样的名称,而且还有一个巨大的安全漏洞,容易受到 SQL 注入的影响。只需按照此处的建议...wiki.hashphp.org/PDO_Tutorial_for_MySQL_Developers .
-
这就是我热衷于使用准备好的语句的确切原因(当然还有撇号问题),但它没有帮助,因此在这里。
-
准备一个包含硬编码参数值的 SQL 语句是没有意义的......你需要类似 $stmt = $connect->prepare('INSERT INTO Contact_table (PHONE, NAME) VALUES(?, ?) ON DUPLICATE KEY UPDATE name = COALESCE(VALUES(name), name)');在循环之前,然后在循环内部: $stmt->execute(array($numbers[$i], $names[$i]));
-
@zgguy:感谢您的解释。但是,这不会导致很多查询,因为我们在循环的每次迭代中都执行一个查询吗?我的目标是将整个批处理作为单个查询执行,这就是为什么我在循环之后保留 query() 函数。另外,我刚刚了解了addslashes() 函数。这对注射足够安全吗?我问这个是因为这个功能确实解决了我的撇号问题。
-
是的,它会引起很多查询,但是由于您只准备一次语句并执行多次,它为数据库节省了很多工作,因为不需要每次都解析和编译发出查询。您也可以尝试准备 INSERT INTO Contact_table (PHONE, NAME) VALUES (?, ?), (?, ?), ... 形式的语句,然后一次绑定所有变量。 addlashes() 将解决您的撇号问题,但准备好的语句绝对是要走的路,尤其是当您考虑到安全性时。
标签: mysql php prepared-statement