我正在寻找一个SQL注入安全技术,在一次插入大量的行(约2000年)与PHP和库MySQLi。
我有所有必须包含值的数组。 目前,我正在做的是:
<?php
$array = array("array", "with", "about", "2000", "values");
foreach ($array as $one)
{
$query = "INSERT INTO table (link) VALUES ( ?)";
$stmt = $mysqli->prepare($query);
$stmt ->bind_param("s", $one);
$stmt->execute();
$stmt->close();
}
?>
我试图call_user_func_array() ,但它引起了计算器。
什么是更快的方法来做到这一点(例如同时将它们全部?),但仍抵御SQL-注射(就像一个准备好的声明)和stackoverflows?
谢谢!
你应该能够把你插入一个事务中大大提高速度。 您也可以将您的准备和绑定陈述你的循环之外。
$array = array("array", "with", "about", "2000", "values");
$query = "INSERT INTO table (link) VALUES (?)";
$stmt = $mysqli->prepare($query);
$stmt ->bind_param("s", $one);
$mysqli->query("START TRANSACTION");
foreach ($array as $one) {
$stmt->execute();
}
$stmt->close();
$mysqli->query("COMMIT");
编辑:
我测试了这个代码与我的Web服务器上万次迭代。
如果没有交易: 226 seconds.
随着交易: 2 seconds.
或two order of magnitude speed increase
,至少对于测试。
再次尝试这个,我不明白为什么你原来的代码将不会与小的修改工作:
$query = "INSERT INTO table (link) VALUES (?)";
$stmt = $mysqli->prepare($query);
$stmt->bind_param("s", $one);
foreach ($array as $one) {
$stmt->execute();
}
$stmt->close();
是的,你可以手动建立一个大的查询,喜欢的东西:
$query = "";
foreach ($array as $curvalue) {
if ($query)
$query .= ",";
$query .= "('" . $mysqli->real_escape_string($curvalue) . "')";
}
if ($query) {
$query = "INSERT INTO table (link) VALUES " . $query;
$mysqli->query($query);
}
你应该先转换您的阵列成一个字符串。 鉴于这是一个字符串数组(而不是二维数组),你可以使用破灭功能。
请注意,每个值应括到括号和正确转义,以确保正确的INSERT
语句,并避免SQL注入的风险。 为了正确逃脱你可以使用引用的方法PDOConnection
-假设你通过PDO连接到MySQL。 要执行你的阵列的每个条目这个操作,您可以使用array_map 。
逃逸每个值,并将它们爆成一个字符串后,你需要把它们放进INSERT
语句。 这是可以做到的sprintf 。
例:
<?php
$connection = new PDO(/*...*/);
$connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$dataToBeSaved = [
'some',
'data',
'with "quotes"',
'and statements\'); DROP DATABASE facebook_main; --'
];
$connection->query(
sprintf(
'INSERT INTO table (link) VALUES %s',
implode(',',
// for each entry of the array
array_map(function($entry) use ($connection) {
// escape it and wrap it in parenthesis
return sprintf('(%s)', $connection->quote($entry));
}, $dataToBeSaved)
)
)
);
注意 :根据记录你愿意插入到数据库中的金额,你可能需要将它们分成几个INSERT
语句。