2016-08-01 78 views
0

我试图通过几个数组循环来将数据插入到mysql数据库中。我试图绑定数据,以便我可以循环访问它。可以有不同数量的列绑定数据。循环遍历一个变量数组并使用bind_param插入

看来数据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,并且没有其他信息被插入。第二次迭代(和所有连续的)导致以下错误消息:重复条目'0'键'PRIMARY'

我在做什么错在这里,它是评估还是别的?我不知道如何找出这一个。

+0

只要添加,如果它不是很明显,数据库表设置与ID作为主键。 – envisteven

+0

无法一目了然,但是把你正在构建的字符串放在一个var中,并在eval之前将其转储,也许在那里有什么不对的地方是不明显的。 – alzee

+0

eval语句的字符串看起来正确:$ ID = 1;和$ Date = now(); – envisteven

回答

0

与其继续尝试使现有代码正常工作,我将建议一个KISS起点,而不要使用prepare(),eval()bind_param()

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

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

+0

我也在想,更简单的选择可能是要走的路。我唯一担心的是处理大量的数据。真的很感谢帮助! – envisteven

+0

我不认为你必须担心这里的数据大小。当你正在改变WHERE子句中的值时,准备好的语句对SELECT更有帮助。使用这些简单的INSERT,将它们放入一个带有小列数的表格中,并没有什么优势。 – alzee