我试图遍历几个数组以将数据插入到mysql数据库中。我试图绑定数据,以便我可以循环它。可以有不同数量的列绑定数据。
似乎未按预期处理数据Im绑定,插入最终失败。
我有一个存储列名和数据类型的列数组。我还有一个值数组,用于存储要插入的值。样本数据:
$colArr = array (
array('i', 'ID'),
array('s', 'Date')
);
$valArr = array(
array(1, 'now()'),
array(2, 'now()'),
);
//I create my type and query strings as well as the array referencing the columns for binding.
$valStrForQry = rtrim(str_repeat('?, ', count($v['colArr'])), ', '); //result: '?, ?'
$params = array();
$colsForQry = '';
$typeStr = '';
$cntr = 0;
foreach ($colArr as $cols) {
$colsForQry .= $cols[1] . ', ';
$typeStr .= $cols[0];
$params[] = &$valArr[$cntr][1];
$cntr++;
}
$colsForQry = rtrim($colsForQry, ', '); //result: 'ID, Date'
$qry = 'INSERT INTO table (' . $colsForQry . ') VALUES (' . $valStrForQry . ')';
$stmt = $mysqli->prepare($qry);
//Bind the parameters.
call_user_func_array(array($stmt, 'bind_param'), array_merge(array($typeStr), $params));
//Loop through the values array, assign them using eval, and execute the statement. Im open to suggestions if theres a better way to do this.
foreach ($valArr as $vals) {
$cntr = 0;
foreach ($colArr as $c) {
eval('$' . $c[1] . ' = ' . $vals[$cntr] . ';');
$cntr++;
}
if ($stmt->execute() === FALSE) {
//show $stmt->error for this iteration
} else {
//show success for this iteration
}
}
第一次迭代导致成功插入不正确的数据。也就是说,插入的ID是0而不是1,并且没有插入其他信息。第二次迭代(以及所有连续的迭代)导致以下错误消息:键'PRIMARY'的重复条目'0'
我在这里做错了什么,是评估还是其他什么?我不知道该如何解决这个问题。
答案 0 :(得分:0)
我没有继续尝试让现有代码正常工作,而是建议使用KISS起点,而不是prepare()
,eval()
或bind_param()
。< / p>
$cols = ['ID', 'Date'];
$vals = [
[1, '\'now()\''],
[2, '\'now()\''],
];
foreach ($vals as $val)
{
$sql = 'INSERT INTO table (' . implode($cols, ', ') . ') VALUES (' . implode($val, ', ') . ')';
// exec here
}
为了使这更安全一点,你可能想要在内爆之前,或在它们被放入你正在使用的数组之前/之前转义所有值。现有的代码是恕我直言,试图过于“聪明”地做一些如此简单的事情。
或者,您可能需要考虑切换到使用PDO库而不是mysqli。 PDO支持在每个参数的基础上绑定命名参数,这可以在没有eval()的循环中完成。
其他人可能会提供所提供的“聪明”解决方案,而不是当然。