I am having trouble using PDO to insert multiple records into a database. I can successfully add a single record, but as soon as I add the foreach
loop, it fails. After reading a number of other SO questions regarding this, I believe I need to "bind" my variables, although I am completely confused on the proper syntax.
Here is the original function I created:
<? function addToDatabase () {
//Get All Variables
$timestamp = date("Y-m-d H:i:s");
$schoolName = $_SESSION['schoolName'];
$schoolStreet = $_SESSION['schoolStreet'];
$schoolCity = $_SESSION['schoolCity'];
$schoolState = $_SESSION['schoolState'];
$schoolZip = $_SESSION['schoolZip'];
$schoolContactName = $_SESSION['schoolContactName'];
$schoolContactTitle = $_SESSION['schoolContactTitle'];
$schoolContactPhone = $_SESSION['schoolContactPhone'];
$schoolCsontactEmail = $_SESSION['schoolContactEmail'];
$inputMethod = $_SESSION['inputMethod'];
$studentDataArray = $_SESSION['studentDataArray'];
$studentFirstNameField = $_SESSION['studentFirstNameField'];
$studentLastNameField = $_SESSION['studentLastNameField'];
$studentStreetField = $_SESSION['studentStreetField'];
$studentCityField = $_SESSION['studentCityField'];
$studentStateField = $_SESSION['studentStateField'];
$studentZipcodeField = $_SESSION['studentZipcodeField'];
$studentDOBField = $_SESSION['studentDOBField'];
$studentGenderField = $_SESSION['studentGenderField'];
$studentGradeField = $_SESSION['studentGradeField'];
//Connnect to Database
$host = 'myHost';
$un = 'myUsername';
$pw = 'myPassword';
$db_name = 'myTable';
try {
$conn = new PDO("mysql:host=$host;dbname=$dbName", $un, $pw);
echo 'Connected to database<br>';
$sql = "INSERT INTO studentData (originallyAddedOn, inputMethod, studentFirst, studentLast, studentStreet, studentCity, studentState, studentZip, studentDOB, studentGender, studentGrade, schoolName, schoolStreet, schoolCity, schoolState, schoolZip, schoolContactName, schoolContactTitle, schoolContactEmail, schoolContactPhone) VALUES (:originallyAddedOn, :inputMethod, :studentFirst, :studentLast, :studentStreet, :studentCity, :studentState, :studentZip, :studentDOB, :studentGender, :studentGrade, :schoolName, :schoolStreet, :schoolCity, :schoolState, :schoolZip, :schoolContactName, :schoolContactTitle, :schoolContactEmail, :schoolContactPhone)";
foreach ($studentDataArray as $student){
$q = $conn->prepare($sql);
echo $student[$studentFirstNameField]."<br>";
$q->execute(array( ':originallyAddedOn'=>$timestamp,
':inputMethod'=>$inputMethod,
':studentFirst'=>$student[$studentFirstNameField],
':studentLast'=>$student[$studentLastNameField],
':studentStreet'=>$student[$studentStreetField],
':studentCity'=>$student[$studentCityField],
':studentState'=>$student[$studentStateField],
':studentZip'=>$student[$studentZipField],
':studentDOB'=>$student[$studentDOBField],
':studentGender'=>$student[$studentGenderField],
':studentGrade'=>$student[$studentGradeField],
':schoolName'=>$schoolName,
':schoolStreet'=>$schoolStreet,
':schoolCity'=>$schoolCity,
':schoolState'=>$schoolState,
':schoolZip'=>$schoolZip,
':schoolContactName'=>$schoolContactName,
':schoolContactTitle'=>$schoolContactTitle,
':schoolContactEmail'=>$schoolContactEmail,
':schoolContactPhone'=>$schoolContactPhone));
}
// close the database connection
$dbh = null;
}
catch(PDOException $e) {
echo $e->getMessage();
}
}
The $studentDataArray
looks similar to this:
0 => //student 1
array
[0] => 'Joe' //First
[1] => 'Smith' //Last
[2] => '101 Main St' //Street
[3] => 'Boston' //City
[4] => 'MA' //State
[5] => '01234' //Zip
[6] => '2000-01-01' //Date of Birth
[7] => 'Male' //Gender
[8] => '12' //Grade
1 => //Student 2
array
[0] => 'Jane'
[1] => 'Smith'
[2] => '99 Main St'
[3] => 'Boston'
[4] => 'MA'
[5] => '01234'
[6] => '2000-02-02'
[7] => 'Female'
[8] => '10'
<? function addToDatabase ($dataArray) {
//Connnect to Database
$host = 'myHost';
$un = 'myUsername';
$pw = 'myPassword';
$db_name = 'myTable';
try {
$conn = new PDO("mysql:host=$host;dbname=$dbName", $un, $pw);
echo 'Connected to database<br>';
$sql = "INSERT INTO studentData (originallyAddedOn, inputMethod, studentFirst, studentLast, studentStreet, studentCity, studentState, studentZip, studentDOB, studentGender, studentGrade, schoolName, schoolStreet, schoolCity, schoolState, schoolZip, schoolContactName, schoolContactTitle, schoolContactEmail, schoolContactPhone) VALUES (:originallyAddedOn, :inputMethod, :studentFirst, :studentLast, :studentStreet, :studentCity, :studentState, :studentZip, :studentDOB, :studentGender, :studentGrade, :schoolName, :schoolStreet, :schoolCity, :schoolState, :schoolZip, :schoolContactName, :schoolContactTitle, :schoolContactEmail, :schoolContactPhone)";
$q = $conn->prepare($sql);
foreach ($dataArray as $student){
$a = array (':originallyAddedOn'=>$student['timestamp'],
':inputMethod'=>$student['inputMethod'],
':studentFirst'=>$student['studentFirst'],
':studentLast'=>$student['studentLast'],
':studentStreet'=>$student['studentStreet'],
':studentCity'=>$student['studentCity'],
':studentState'=>$student['studentState'],
':studentZip'=>$student['studentZip'],
':studentDOB'=>$student['studentDOB'],
':studentGender'=>$student['studentGender'],
':studentGrade'=>$student['studentGrade'],
':schoolName'=>$student['schoolName'],
':schoolStreet'=>$student['schoolStreet'],
':schoolCity'=>$student['schoolCity'],
':schoolState'=>$student['schoolState'],
':schoolZip'=>$student['schoolZip'],
':schoolContactName'=>$student['schoolContactName'],
':schoolContactTitle'=>$student['schoolContactTitle'],
':schoolContactEmail'=>$student['schoolContactEmail'],
':schoolContactPhone'=>$student['schoolContactPhone']);
if ($q->execute($a)) {
// Query succeeded.
} else {
// Query failed.
echo $q->errorCode();
}
// close the database connection
$dbh = null;
echo "Insert Complete!";
}
}
catch(PDOException $e) {
echo $e->getMessage();
}
}
You dont need to bind your variables. Ive done this before with similar code. Its hard to say whats going wrong though. Do you get an exception - if so what is it?
The only thing i see wrong is you have your preparation inside the loop... should be more like:
try {
$conn = new PDO("mysql:host=$host;dbname=$dbName", $un, $pw);
echo 'Connected to database<br>';
$sql = "INSERT INTO studentData (originallyAddedOn, inputMethod, studentFirst, studentLast, studentStreet, studentCity, studentState, studentZip, studentDOB, studentGender, studentGrade, schoolName, schoolStreet, schoolCity, schoolState, schoolZip, schoolContactName, schoolContactTitle, schoolContactEmail, schoolContactPhone) VALUES (:originallyAddedOn, :inputMethod, :studentFirst, :studentLast, :studentStreet, :studentCity, :studentState, :studentZip, :studentDOB, :studentGender, :studentGrade, :schoolName, :schoolStreet, :schoolCity, :schoolState, :schoolZip, :schoolContactName, :schoolContactTitle, :schoolContactEmail, :schoolContactPhone)";
// prepare once... exceute many :-)
$q = $conn->prepare($sql);
foreach($studentDataArray as $student) {
$q->execute($yourDataArray);
// do other stuff if needed
}
} catch(PDOException $e) {
echo $e->getMessage();
}
For loops, do this (PDO or other database client libraries that support prepared statements):
INSERT
query.Profit.
For a PDO based example on an array with data to insert into some table that requires a single column named option
.
First some data to be inserted into the database:
$options = [
['option' => "Insert Option A " . uniqid()],
['option' => "Insert Option B " . uniqid()],
['option' => "Insert Option C " . uniqid()],
];
Somewhere else, let's assume to have that $options
array and care about the database interaction. This needs a connection:
$conn = new PDO('mysql:dbname=test;host=localhost', 'testuser', 'test');
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$conn->setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE);
Now let's prepare the insert query. Using named parameters here like in the question, sure this works with numbered parameters, too:
$stmt = $conn->prepare('INSERT INTO config (`OPTION`) VALUES (:OPTION);');
Now let's bind the named parameter to a variable here. Take note, that the variable is prefixed (here with insert
). This is actually the aliasing to the option
key in the input array:
$stmt->bindParam(':OPTION', $insert_option);
So now from the numbered list above, the points 1.) prepare the SQL INSERT
query. and 2.) bind the variables. has been done.
Only left is the loop over the $options
array to insert the values:
foreach ($options as $insert) {
extract($insert, EXTR_PREFIX_ALL, 'insert');
$stmt->execute();
}
Making use of extract
allows to set multiple variables at once based on the input array in an aliased fashion without much ado.
The full example:
$options = [
['option' => "Insert Option A " . uniqid()],
['option' => "Insert Option B " . uniqid()],
['option' => "Insert Option C " . uniqid()],
];
$conn = new PDO('mysql:dbname=test;host=localhost', 'testuser', 'test');
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$conn->setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE);
# 1. Prepare
$stmt = $conn->prepare('INSERT INTO config (`OPTION`) VALUES (:OPTION);');
# 2. Bind
$stmt->bindParam(':OPTION', $insert_option);
# 3. Loop & Execute
foreach ($options as $insert) {
extract($insert, EXTR_PREFIX_ALL, 'insert');
$stmt->execute();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With