循环遍历变量数组并使用bind_param插入

时间:2016-08-01 19:04:37

标签: php mysqli bindparam

我试图遍历几个数组以将数据插入到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'

我在这里做错了什么,是评估还是其他什么?我不知道该如何解决这个问题。

1 个答案:

答案 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()的循环中完成。

其他人可能会提供所提供的“聪明”解决方案,而不是当然。