PDO多插入问题

Here is a chunk of my php script that must be missing something:

$startIndex = 7;
$endIndex = 303;
$defaults = range($startIndex, $endIndex);

$sql = "INSERT INTO items (itemId, userId) VALUES ";
$part = array_fill(0, count($defaults), "(?, ?)");
$sql .= implode(",", $part);
try {
  $db = DB::getInstance();
  $stmt = $db->dbh->prepare($sql);
  $i = 1;
  foreach($defaults as $default) {
    $stmt->bindParam($i++, $default);
    $stmt->bindparam($i++, $userId);
  }
  if ($stmt->execute()) {
    echo "result=ok";
  }else {
    echo 'invalid query';
  }

}catch(PDOException $e) {
  echo $e->getMessage();
}

The multiple inserts are happening and everything seems good, except all of the itemId fields are coming in as 303(the last element in the $defaults array). The foreach loop seems to be working as I expected as echoing $default gives me the sequence of ints I expect. So, it must be a problem with the binding

Please help :)

What happens here is you bound the parameter to the $default variable, not it's value.

The value of $default changes as you loop the $defaults array. The bound parameter is using the reference, not a copy.

You could change your loop and bound parameter to reference the array item:

foreach($defaults as $key => $default) {
    $stmt->bindParam($i++, $defaults[$key]);
    $stmt->bindparam($i++, $userId);
}

bindParam requires a reference. It binds the variable, not the value, to the statement.

You can solve the problem by passing by reference:

foreach($defaults as &$default) {          //pass $default as a reference (&)
    $stmt->bindParam($i++, $default);     // bind the variable to the statement
}

or by passing by value and using bindValue instead of bindParam:

foreach($defaults as &$default) {  
    $stmt->bindValue($i++, $default);     // bind the value to the statement
}