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'
UPDATE: For those that are interested, here is my final function after I fixed the errors:
<? 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):
prepare the SQL INSERT query.
bind the variables.
loop your array against the bind variables, execute once per iteration.
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();
}
Related
I am currently converting my mySQLi PHP code into PDO for better security and I am having some trouble understanding how I can convert the code below and implement it into my new PDO PHP
The code below should take the last inserted ID (the one the PDO is inserting) and set the column idnum equal to the NUM(and the last inserted id).
How can this be converted and added to the PDO?
if (mysqli_query($conn, $sql)) {
$last_id = mysqli_insert_id($conn);
$sql = "UPDATE Equipment SET idnum = CONCAT('NUM', '$last_id') WHERE equipment_id = '$last_id'";
mysqli_query($conn, $sql);
echo "New record created successfully. Last inserted ID is: " . last_id;
} else {
echo "Error: " . $sql . "<br>" . mysqli_error($conn);
}
mysqli_close($conn);
I would like to add the code to the following PDO PHP script:
$hostdb = 'localhost';
$namedb = 'dbname';
$userdb = 'userdb';
$passdb = 'passdb';
$charset = 'utf8';
if (isset($_POST['name'], $_POST['place'], $_POST['person'] , $_POST['number'] , $_POST['other_name'])) {
// Connect and create the PDO object
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_EMULATE_PREPARES => false,
];
$conn = new PDO("mysql:host=$hostdb;dbname=$namedb;charset=$charset", $userdb, $passdb, $options);
$stmt = $conn->prepare( ' INSERT INTO `Table1` (name, place, person, number, other_name, progress)
VALUES (:name,:place,:person,:number,:other_name, "Done") ' );
$stmt->execute([
'name' => $_POST['name'],
'place' => $_POST['place'],
'person' => $_POST['person'],
'number' => $_POST['number'],
'other_name' => $_POST['other_name'],
]);
// Shows the number of affected rows
echo 'Affected rows : '. $stmt->rowCount();
}
Like this I guess (if you want them combined):
$hostdb = 'localhost';
$namedb = 'dbname';
$userdb = 'userdb';
$passdb = 'passdb';
$charset = 'utf8';
if (isset($_POST['name'], $_POST['place'], $_POST['person'] , $_POST['number'] , $_POST['other_name'] )) {
// Connect and create the PDO object
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_EMULATE_PREPARES => false,
];
$conn = new PDO("mysql:host=$hostdb;dbname=$namedb;charset=$charset", $userdb, $passdb, $options);
try{
//start a transaction {ACID}
$conn->beginTransaction();
$stmt = $conn->prepare('INSERT INTO `Table1` (`name`, `place`, `person`, `number`, `other_name`, `progress`)
VALUES (:name,:place,:person,:number,:other_name, "Done") ' );
$stmt->execute([
'name' => $_POST['name'],
'place' => $_POST['place'],
'person' => $_POST['person'],
'number' => $_POST['number'],
'other_name' => $_POST['other_name'],
]);
//get the last insert ID
$last_id = $conn->lastInsertId();
$stmt = $conn->prepare('UPDATE `Equipment` SET `idnum` = CONCAT("NUM", :last_id_0) WHERE `equipment_id` = :last_id_1');
//named placeholders must be unique
$stmt->execute([
'last_id_0' => $last_id,
'last_id_1' => $last_id
]);
echo "New record created successfully. Last inserted ID is: " . $last_id;
//commit the changes
$conn->commit();
}catch(PDOException $e){
//roll back the changes on errors
$conn->rollback();
echo $e->getMessage();
}
// Shows the number of affected rows this is pointless (for insert 1 row it's always 1 or an error)
//echo 'Affected rows : '. $stmt->rowCount();
}
Transactions are like changing the DB for pretend (if it's INNODB table), then if there is an error with one of the query both fail.
It's advisable to use them when creating related records that way you don't leave orphan records or rows without the relationship just hanging around.
I have a table like so.
CREATE TABLE `GBPAUD` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`currency_pair` varchar(11) NOT NULL DEFAULT '',
`date` datetime NOT NULL,
`sell` float NOT NULL,
`buy` float NOT NULL,
`spread` float NOT NULL,
PRIMARY KEY (`id`)
)
I have written a script that opens CSV files, itterates the rows and inserts them into the table.
After the script has run and i look in the database the table appears like this.
The code that inserts the data looks like so.
private function insert($currencyPair, $date, $buy, $sell, $spread){
$this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$result_set = $this->pdo->prepare("INSERT INTO ".str_replace('_', '', $this->instrument)." (currency_pair, date, sell, buy, spread) VALUES (:currency_pair, :date, :sell, :buy, :spread)");
$result = $result_set->execute(array(':currency_pair' => $currencyPair, ':date' => $date, ':buy' => (float)$buy, ':sell' => (float)$sell, 'spread' => (float)$spread));
}
I print out the values just before the exacute stament and the values are correct.
Array
(
[:currency_pair] => GBP/AUD
[:date] => 2007-11-01 14:06:04.000
[:buy] => 2.273400
[:sell] => 2.272500
[spread] => 0
)
Anyone have any idea why its not inserting my data?
EDIT:
DB connection code
define("DSN", "mysql:dbname=rates_test;host=localhost;port=3306");
define("USER", "blah");
define("PASS", "blah");
$pdo = new PDO(DSN, USER, PASS);
EDIT 2
I have taken the insert out of the function and added to the while loop im doing so you can see whats happening.
while( false !== ( $data = fgetcsv($file) ) ) {
if(array(null) !== $data){ //skip blank lines
$currencyPair = $data[$column['columns']['instrument']];
$date = $data[$column['columns']['date']];
$sell = $data[$column['columns']['sell']];
$buy = $data[$column['columns']['buy']];
$spread = (float)$buy - (float)$sell;
echo "value => " . $currencyPair . "\r\n";
echo "value => " . $date . "\r\n";
echo "value => " . $sell . "\r\n";
echo "value => " . $buy . "\r\n";
echo "value => " . $spread . "\r\n";
echo var_dump(array(':currency_pair' => $currencyPair, ':date' => $date, ':buy' => (float)$buy, ':sell' => (float)$sell, ':spread' => (float)$spread));
$result_set = $this->pdo->prepare("INSERT INTO ".str_replace('_', '', $this->instrument)." (currency_pair, date, sell, buy, spread) VALUES (:currency_pair, :date, :sell, :buy, :spread)");
$result = $result_set->execute(array(':currency_pair' => $currencyPair, ':date' => $date, ':buy' => (float)$buy, ':sell' => (float)$sell, ':spread' => (float)$spread));
}
}
and here is the result
value => GBP/AUD
value => 2007-10-28 21:21:48.000
value => 2.229000
value => 2.229900
value => 0
array(5) {
[":currency_pair"]=> string(15) "GBP/AUD"
[":date"]=> string(47) "2007-10-28 21:21:48.000"
[":buy"]=> float(0)
[":sell"]=> float(0)
[":spread"]=> float(0)
}
Edit 3:
I solved it, but its a bit hacky. Also i have no control over over these CSV's so any invisible characters can be in it. Can anyone please confirm if this is enough to handle any invisible characters there may be? ( i have not put this into a function yet, but i am doing the same for ever variable im inserting)
$buy = preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $buy);
$buy = (strpos($buy, ':') && strpos($buy, '-')) ? array_shift(explode('.', $buy)) : $buy;
I do not like what i am doing with the date, but i cannot think of any other ways (i cannot parse a legitamate date straight from the CSV because of the invisable characters) even without the invisible characters removed i cannot parse a date because some feilds have more than 6 micro seconds (PHP can only handel 6)
I just wrapped a bit of code around your posted code and it works fine. I did not even change the code for the spread to :spread suggestion.
I did however add a try/catch block as I see you set the mode to throw Exceptions, but the catch block was never activated.
<?php
class tst
{
private $pdo;
private $instrument = 'gbp_aud';
public function __construct()
{
/*** mysql hostname ***/
$hostname = 'localhost';
/*** mysql username ***/
$username = 'test';
/*** mysql password ***/
$password = 'test';
/*** database name ***/
$dbname = 'test';
try {
$this->pdo = new PDO("mysql:host=$hostname;dbname=$dbname;charset=UTF8", $username, $password);
$this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$this->pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
$this->pdo->setAttribute(PDO::MYSQL_ATTR_INIT_COMMAND,'SET NAMES UTF8');
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
exit;
}
}
private function insert($currencyPair, $date, $buy, $sell, $spread){
$this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
try {
$result_set = $this->pdo->prepare("INSERT INTO ".str_replace('_', '', $this->instrument)." (currency_pair, date, sell, buy, spread) VALUES (:currency_pair, :date, :sell, :buy, :spread)");
$result = $result_set->execute(array(':currency_pair' => $currencyPair, ':date' => $date, ':buy' => (float)$buy, ':sell' => (float)$sell, 'spread' => (float)$spread));
}
catch(PDOException $e) {
print_r($this->pdo->errorInfo());
exit;
}
}
public function doit($currencyPair, $date, $buy, $sell, $spread){
$this->insert($currencyPair, $date, $buy, $sell, $spread);
}
}
$test = new tst();
$currencyPair = 'GBP/AUD';
$date = '2007-11-01 14:06:04.000';
$buy = 2.273400;
$sell = 2.272500;
$spread = 0;
$test->doit($currencyPair, $date, $buy, $sell, $spread);
$currencyPair = 'GBP/AUD';
$date = '2007-11-02 13:06:04.000';
$buy = 2.276600;
$sell = 2.278800;
$spread = 0.4;
$test->doit($currencyPair, $date, $buy, $sell, $spread);
Results:
I just read your last question, and I have to assume that you still have some odd characters in your data feed to this process.
Do a var_dump() of the array that you feed to the ->execute() statement, that will likely show more than a simple print_r()
UPDATE
The issue is that the older files are encoded in UNICODE and the new files are simple ASCII single byte encoded.
I converted the Older files offline so to speak back to ASCII and this code loaded an old and new file quite happily
The only remaining complication if that the older files dont have column names on row 1 and the field order is a little different, but thats just a FLOC. See the code below.
<?php
class tst
{
private $pdo;
private $instrument = 'gbp_aud';
public function __construct()
{
/*** mysql hostname ***/
$hostname = 'localhost';
/*** mysql username ***/
$username = 'test';
/*** mysql password ***/
$password = 'test';
/*** database name ***/
$dbname = 'test';
try {
$this->pdo = new PDO("mysql:host=$hostname;dbname=$dbname;charset=UTF8", $username, $password);
$this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$this->pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
$this->pdo->setAttribute(PDO::MYSQL_ATTR_INIT_COMMAND,'SET NAMES UTF8');
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
exit;
}
}
private function insert($currencyPair, $date, $buy, $sell, $spread){
$this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
try {
$result_set = $this->pdo->prepare("INSERT INTO ".str_replace('_', '', $this->instrument)." (currency_pair, date, sell, buy, spread) VALUES (:currency_pair, :date, :sell, :buy, :spread)");
$result = $result_set->execute(array(':currency_pair' => $currencyPair, ':date' => $date, ':buy' => (float)$buy, ':sell' => (float)$sell, 'spread' => (float)$spread));
}
catch(PDOException $e) {
print_r($this->pdo->errorInfo());
exit;
}
}
public function doit($currencyPair, $date, $buy, $sell, $spread){
$this->insert($currencyPair, $date, $buy, $sell, $spread);
}
}
$test = new tst();
// One old and one new format file
$files = array('GBP_AUD_Week1.csv', 'GBP_AUD_Week5.csv');
foreach ($files as $file) {
$old_format = true;
if (($handle = fopen($file, "r")) !== FALSE) {
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
// test old or new file layout
if ( $data[0] == 'lTid' ) {
// New file layout
$old_format = false;
// Skip the title row
continue;
}
if ( $old_format ) {
$test->doit($data[1], $data[2], $data[3], $data[4], $data[4]-$data[3]);
} else {
$test->doit($data[2], $data[3], $data[4], $data[5], $data[5]-$data[4]);
}
}
fclose($handle);
}
}
Reccently I have been attempting to insert an array into a database, I keep getting the error message "Notice: Array to string conversion", I not really sure how to resolve this issue, any advice would be greatly appreciated
<?php
try{
$db = new PDO("mysql:host=localhost;dbname=test", 'root', '');
$db ->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(PDOException $e){
echo $e->getMessage();
die();
}
if ($_SERVER["REQUEST_METHOD"] == "POST"){
$sort = $_POST['sort'];
$count = $_POST["count"];
$error = $_POST["error"];
$audit = array( ':sort' => $sort,
':count' => $count,
':error' => $error
);
foreach($audit as $completeAudit => $display) {
//print_r($display);
$sql = implode("INSERT INTO `audits` (`sort`, `count`, `error`, `timeentered`) VALUES ('$sort','$count','$error', NOW())");
}
$query = $db->prepare($sql);
$query->execute(array(
':sort' => $sort,
':count' => $count,
':error' => $error
));
}
EDIT
$db = new PDO("mysql:host=localhost;dbname=test", 'root', '');
$db ->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
if ($_SERVER["REQUEST_METHOD"] == "POST"){
$sql = "INSERT INTO `audits` (`sort`, `count`, `error`, `timeentered`) VALUES (?,?,?, NOW())";
$stmt = $db->prepare($sql);
$query->execute(array($_POST['sort'], $_POST["count"], $_POST["error"]));
}
This is how it looks now, I deleted everything and used code supplied below
The problem is probably with the implode() call. It requires an array as parameter but you're passing a string.
However, you're overriding the $sql variable in every iteration inside the loop so I'm not sure what it's supposed to do.
Last thing, your code is subject to SQL inejctions so have a look at using prepared statements.
this error has nothing to do with PDO - it's just basic PHP syntax.
However, your PDO is wrong as well. Here is the proper code:
$db = new PDO("mysql:host=localhost;dbname=test", 'root', '');
$db ->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
if ($_SERVER["REQUEST_METHOD"] == "POST"){
$sql = "INSERT INTO `audits` (`sort`, `count`, `error`, `timeentered`) VALUES (?,?,?, NOW())");
$stmt = $db->prepare($sql);
$stmt->execute(array($_POST['sort'], $_POST["count"], $_POST["error"]));
}
I have a class formhandller like this
<?php
include "config.php";
class formhandller {
var $dbinstance;
var $lastinsertedid;//The id from the basic information tabel
function __construct(){
$this->connectDb();
}
function pdoMultiInsert($tableName, $data, $pdoObject){
//Will contain SQL snippets.
$rowsSQL = array();
//Will contain the values that we need to bind.
$toBind = array();
//Get a list of column names to use in the SQL statement.
$columnNames = array_keys($data[0]);
//Loop through our $data array.
foreach($data as $arrayIndex => $row){
$params = array();
foreach($row as $columnName => $columnValue){
$param = ":" . $columnName . $arrayIndex;
$params[] = $param;
$toBind[$param] = $columnValue;
}
$rowsSQL[] = "(" . implode(", ", $params) . ")";
}
//Construct our SQL statement
$sql = "INSERT INTO `$tableName` (" . implode(", ", $columnNames) . ") VALUES " . implode(", ", $rowsSQL);
//Prepare our PDO statement.
$pdoStatement = $pdoObject->prepare($sql);
//Bind our values.
foreach($toBind as $param => $val){
$pdoStatement->bindValue($param, $val);
}
//Execute our statement (i.e. insert the data).
try {
return $pdoStatement->execute();
} catch(PDOException $e) {
var_dump($e->getMessage());
//show error
error_log($query." :".$e->getMessage(). "\n", 3, getcwd() . "/var/tmp/sql_error.log");
exit;
}
}
private function connectDb(){
try {
//create PDO connection
$this->dbinstance = new PDO("mysql:host=".DBHOST.";dbname=".DBNAME, DBUSER, DBPASS);
$this->dbinstance->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(PDOException $e) {
//show error
error_log($query." :".$e->getMessage(). "\n", 3, getcwd() . "/var/tmp/sql_error.log");
exit;
}
}
public function postBasicinformation(){
//Add the variables coming from the form .
$stmt = $this->dbinstance->prepare('INSERT INTO basic_information (company,name,designation,email,direct_line,mobile) VALUES (:company, :name, :designation, :email, :directline, :mobile)');
$stmt->execute(array(
':company' => $_POST['company'],
':name' => $_POST['name'],
':designation' => $_POST['designation'],
':email' => $_POST['email'],
':directline' => $_POST['directline'],
':mobile' => $_POST['mobile'],
));
$this->lastinsertedid = $this->dbinstance->lastInsertId('id');
//echo $this->lastinsertedid;
//$this->dbinstance=null;
}
public function postProjectawards(){
//An example of adding to our "rows" array on the fly.
for($i=0;$i<sizeof($_POST['nominee_company']);$i++){
$rowsToInsert[] = array(
'biid' => $this->lastinsertedid,
'award_type' => 'pa',
'category' => $_POST['nominee_category'][$i],
'company' => $_POST['nominee_company'][$i],
'name' => $_POST['nominee_name'][$i],
'designation' => $_POST['nominee_designation'][$i],
'award_title' => $_POST['nominee_title'][$i],
'contact' => $_POST['nominee_contact'][$i],
'email' => $_POST['nominee_email'][$i],
'remark' => $_POST['remarks'][$i]
);
}
//var_dump($rowsToInsert);
//Call our custom function.
$y =$this->pdoMultiInsert('nominee', $rowsToInsert, $this->dbinstance);
//$this->dbinstance=null;
}
}
Now my redirect page is like this
<?php
include "controller/formhandller.php";
$x = new formhandller();
if(isset($_POST['steps'])){
if($_POST['steps']==1){
$x->postBasicinformation();
$url = "nominee.php";
header('Location: '.$url);
die();
}
if($_POST['steps']==2){
$x->postProjectawards();
$url = "nominee2.php";
header('Location: '.$url);
die();
}
}
else {
header('Location: '.'index.php');
die();
}
When I am saving the first step that is using postBasicinformation() this function .
It saves in a table called basic_information and gets the id of the inserted row and initialize it to the variable
$lastinsertedid
I want to use this variable in all the next steps to store in other tables.
But right now I am getting NULL
any Idea
Thanks.
I think you are getting confused about the life cycle of a php script.
Anything you do in xxx.php is lost once that script finishes. All objects instantiated during the execution of xxx.php with be lost forever once it finishes.
If you want to preserve some information created in xxx.php for use in yyy.php you have to save it somewhere, either a file or a database or the SESSION or possibly a caching system.
I think this is where you are getting confused. So as you said in a comment if you want to use this lastinsertid in another script the most obvious place to save it between scripts is the $_SESSION array
I'm trying to create a SQL query using PHP in which it checks to see if a row has already been submitted/set using the same date and user name. If it hasn't it inserts a new row. If it does find a match, it updates the row instead.
I can insert a new row fine, but when I use a pre-existing date and name, I receive no error in any of my logs, and the query appears to run without any problems. But when checking the database, I notice that there are no UPDATES actually set to the row. When I run the update command manually in SQL, it appears to work fine.
Having no logs/error data to go on, I was hoping to get some advice here. I'm sure there must be something I'm missing here. This is what I'm currently using:
require_once 'db-conn.php';
$name = $_POST['name'];
$email = $_POST['email'];
$date = $_POST['date'];
$var1 = $_POST['var1'];
$var2 = $_POST['var2'];
$var3 = $_POST['var3'];
$var4 = $_POST['var4'];
$conn = db_connect ();
$sqlq = "SELECT * FROM tbl WHERE date = '$date' AND name = '$name'";
$nRows = $conn->query("$sqlq")->fetchColumn();
if ($nRows==0) {
try {
$sqli = "INSERT INTO tbl (name,email,date,var1,var2,var3,var4) VALUES (:name,:email,:date,:var1,:var2,:var3,:var4)";
$sql = $conn->prepare("$sqli");
$sql->execute(array(':name' => $name, ':email' => $email, ':date' => $date, ':var1' => $var1, ':var2' => $var2, ':var3' => $var3 ':var4' => $var4));
} catch(PDOException $e) {
die ('SQL Error');
}
}
else {
try {
$sqli = "UPDATE tbl SET email='$email', notes='$notes', var1='$var1', var2='$var2', var3='$var3' WHERE date='$date' AND name='$name'";
$sql = $conn->prepare("$sqli");
$sql->execute(array($name, $email, $date, $var1, $var2, $var3, $var4));
} catch(PDOException $e) {
die ('SQL Error');
}
}
You don't have the bound variables correct:
$sqli = "UPDATE tbl SET email=:email, notes=:notes, var1=:var1, var2=:var2, var3=:var3 WHERE date=:date AND name=:name";
$sql = $conn->prepare("$sqli");
$sql->execute(array(':name' => $name, ':email' => $email, ':date' => $date, ':var1' => $var1, ':var2' => $var2, ':var3' => $var3, ':notes'=>$notes));
You did it correct in the Insert statement but not in the update.
Not sure where you are getting $notes from though.
Plus not sure if it is intentional or not but you are not updating var4 in the update query.