I have a booking system and need to insert the details into mysql database. All of my variables are strings and one of them is an array - so I need to insert the same information for each array element ($ticketnumber). I have tried doing it with a foreach loop, but it doesn't seem to work. How do I do this with only one INSERT statement as people may choose different number of tickets to buy?
Here is part of the code:
<?php
$day = $_SESSION['date'];
$time = $_SESSION['time'];
$name = $_REQUEST['name'];
$ticketnumber = $_REQUEST['tickets']; //this is the array variable
foreach ($ticketnumber as $ticket){
$sql = "INSERT INTO table VALUES ('$name', '$day', '$time', '$ticket');";
$handle = $conn->prepare($sql);
$handle->execute();
}
?>
The values of my array in this case are(it varies depending on how many tickets you check):
array(2) { [0]=> string(3) "010" [1]=> string(3) "011" }
This matched the value of $ticket as well, why is that happening?
My session and connection to the database are established before this. I also tried replacing the array variable with a string and the insert statement works.
Any help is appreciated!
Thank you.
If you concatenate values into the SQL string as you are doing, there's not much benefit to using a prepared statement. Instead, prepare a statement with placeholders and execute it repeatedly for the various different values.
Create an array of parameters
$params['day'] = $_SESSION['date'];
$params['time'] = $_SESSION['time'];
$params['name'] = $_REQUEST['name'];
Create the prepared statement with placeholders where your values will be bound
$sql = "INSERT INTO table VALUES (:name, :day, :time, :ticket);";
$handle = $conn->prepare($sql);
Execute the statement in a loop for each value in $ticketnumber.
$ticketnumber = $_REQUEST['tickets'];
foreach ($ticketnumber as $ticket) {
$params['ticket'] = $ticket; // assign the current ticket to the array of values
$handle->execute($params); // the values are bound to the prepared statement
}
You don't really need to explicitly close or null the connection (especially not inside the loop as others have pointed out).
Related
I'm having trouble with a PDO insert.
I'd like to insert a multidimensional array into a db, which i managed to.
However, i also would like to insert a completely different array, disconnected from the first one into the same db line (which means same INSERT query).
1st multidimensional array = $_POST['training']
2nd array = $training_diploma
Kinda difficult to explain. Here is the code :
$id = "1";
$training_diploma = ("master", "bachelor");
$id_training_key = $id_training_key = $id.'_'.$training_diploma; (return: 1_master)
$sql = "INSERT INTO users_resumes (id,resume_category,id_training_key,training_diploma,training_school,training_level,training_start_date,training_end_date) VALUES ($id,'Training',$id_training_key,:training_diploma,:training_school,:training_level,:training_start_date,:training_end_date)";
$stmt= $pdo->prepare($sql);
foreach($_POST['training'] as $params){
$stmt->execute($params);
}
Any help is very welcome !!! Thx a looot !
You need to iterate the $training_diploma array as well as the $_POST array. It would be better to also include the id and id_training_key as parameters in your query so you don't have to prepare a new query for each set of values:
$id = "1";
$training_diploma = array("master", "bachelor");
$sql = "INSERT INTO users_resumes (id,resume_category,id_training_key,training_diploma,training_school,training_level,training_start_date,training_end_date) VALUES (:id,'Training',:id_training_key,:training_diploma,:training_school,:training_level,:training_start_date,:training_end_date)";
$stmt= $pdo->prepare($sql);
foreach($_POST['training'] as $params) {
foreach ($training_diploma as $diploma) {
$stmt->execute(array_merge($params, array('id' => $id, 'id_training_key' => $id . '_' . $diploma)));
}
}
I'm trying for the last few days but I just can't get this figured out. I have a filter page where the user can select the start_date, end_date, client and paying_status. Client and paying_status are referencing to the main service table.
I even echo all the $_POST and get the right inputs but my SQL query isn't producing any results. When I run the same query on my database, I get the right results. I don't see any errors or I'm getting blind over my own mistakes after all these days.
<?php
include "../controller/session.php";
include "../controller/pdo.php";
$submit = isset($_POST["filter-submit"]) ? $_POST["filter-submit"] : "";
$date_start = isset($_POST["date_start"]) ? $_POST["date_start"] : "";
$date_end = isset($_POST["date_end"]) ? $_POST["date_end"] : "";
$client = isset($_POST["client"]) ? $_POST["client"] : "";
$payed = isset($_POST["payed"]) ? $_POST["payed"] : "";
echo $date_start . "<br>" . $date_end . "<br>" . $client . "<br>" . $payed . "<br>";
if ($submit == "Filter") {
$query = $db->prepare("SELECT * from service where(date BETWEEN ':date_start'AND ':date_end') AND clientId=:client AND paying_status=:payed;");
$query->bindParam(':date_start', $date_start);
$query->bindParam(':date_end', $date_end);
$query->bindParam(':client', $client);
$query->bindParam(':payed', $payed);
$results = $query->fetchAll(PDO::FETCH_OBJ);
var_dump($results);
}
2019-01-01
2019-07-03
1
1
array(0) {}
Above are the $_POST inputs and the empty array. I don't know where to watch anymore.
EDIT:
SELECT * from service where(date BETWEEN '2019-01-01'AND '2019-07-03') AND clientId=1 AND paying_status=1;
This works fine on my database.
EDIT 2: Updated code. Still doesn't work.
if ($submit == "Filter") {
$query = $db->prepare("SELECT * from service where(date BETWEEN ':date_start'AND ':date_end') AND clientId=:client AND paying_status=:payed;");
$query->bindParam(':date_start', $date_start);
$query->bindParam(':date_end', $date_end);
$query->bindParam(':client', $client, PDO::PARAM_INT);
$query->bindParam(':payed', $payed, PDO::PARAM_INT);
$query->execute();
$results = $query->fetchAll(PDO::FETCH_OBJ);
var_dump($results);
}
EDIT 3:
if ($submit == "Filter") {
$query = $db->prepare("SELECT * from service where(date BETWEEN :date_start AND :date_end) AND clientId=:client AND paying_status=:payed;");
$query->bindParam(':date_start', $date_start);
$query->bindParam(':date_end', $date_end);
$query->bindParam(':client', $client, PDO::PARAM_INT);
$query->bindParam(':payed', $payed, PDO::PARAM_INT);
$query->execute();
$results = $query->fetchAll(PDO::FETCH_OBJ);
var_dump($results);
}
This works! Can someone explain why i sometimes need to execute the query and sometimes I just can fetch the data with fetchAll or just fetch? When do i need to execute and when can I just fetch? Thanks
You are getting the '..number of bound variables ...' error because as #Xatenev says you don't need to quotes around your place markers. What you are asking PDO to prepare is the string '...BETWEEN :date_start AND ... i.e. it looks for a date with STRING VALUE OF ':date_start' which presumably doesn't exist, rather than looking for a date value with the value of :date_start.
If should look like this:
from service where(date BETWEEN :date_start .....
just to expand slightly, the actual error then occurs because you try to bind the values for each of the quoted placeholders, but PDO cannot see these placeholders at all, as all it can interpret are some strings you have added and two placemarkers
If you remove your quotes then it no longer sees this as a string and will view it as the place marker as intended
UPDATE -
Re OPs comments about not quite understanding, imagine you have a variable $values
$values[] contains 'jam','bread', or 'peanut butter' depending on the input.
So you want to insert into a table called sandwich_parts and you create a query based on the input (or selection, or loop for whatever)
foreach($values as $value){
$q1->prepare("INSERT INTO sandwich_parts (part) values (':value'));
$q2->prepare("INSERT INTO sandwich_parts (part) values (:value));
$q->bindValue(':value',$value,PDO::PARAM_STR);
}
this would be sent to mysql on execute() as
INSERT INTO sandwich_parts (part) values (':value')
INSERT INTO sandwich_parts (part) values ('jam')
INSERT INTO sandwich_parts (part) values (':value')
INSERT INTO sandwich_parts (part) values ('bread')
INSERT INTO sandwich_parts (part) values (':value')
INSERT INTO sandwich_parts (part) values ('peanut butter')
because the first insert always reads the string ':value' whereas the second sees the place marker and binds the parameter, as such you would get errors for the first query each time because it cannot see a placeholder to bind the value to
I hope that helps your understanding a little, basically, you don't need to quote placeholders that is what the binding process is for
Here's my dilemma, I'm at a loss. I'm trying to add multiple values from an array into a database by looping through them with a prepared mysql statement:
If I "execute" the statement within the foreach loop it only adds the
last entry from the array.
If I "execute" it outside of the loop it inserts 3 individual rows to the database. I would like all columns filled out under one created now() date and row.
If I prepare the $stmt before the foreach loop, then it errors undefined variable. So I've put it after defining in the loop, even though in w3schools it shows that you can define the "bind_param" variables prior to setting parameters, which I don't understand either. Thanks!
foreach ($products as $v) {
$product_was = $v['name'];
$product_now = $v['name'];
$was = $v['was'];
$now = $v['now'];
$stmt = $conn->prepare("INSERT INTO $table_name (date_created, $product_was, $product_now) VALUES (now(), ?, ?)");
$stmt->bind_param("ss", $was, $now);
$stmt->execute();
}
$stmt->close();
$conn->close();
I am inserting the $_POST contents of my PHP array into a table with PDO. I was looking at the following lines of code and I had one of those "there has to be a better way to do this" moments. If the key name matches the column name in the table, is there a more simple way to insert all of it?
Code for example:
$statement = $db->prepare("INSERT INTO `applications`(`username`, `email`, `password`, `name`) VALUES (?,?,?,?)");
$statement->execute(array($_POST['username'], $_POST['email'],$_POST['password'],$_POST['name']));
This code WORKS but it just seems a bit over-the-top (especially as more and more columns are added).
I would do it this way:
Declare the columns first. We'll use these to extract a subset of $_POST for use as columns. Otherwise a user could pass bogus request parameters that don't match any columns of the table, which would break our SQL.
$columns = array('username','email','password','name');
$column_list = join(',', $columns);
Create named parameter placeholders i.e. :username.
$param_list = join(',', array_map(function($col) { return ":$col"; }, $columns));
Form the SQL separately, because it's easier to read and debug if it's in its own variable.
$sql = "INSERT INTO `applications` ($column_list) VALUES ($param_list)";
Always check for error status returned from prepare() and execute().
$statement = $db->prepare($sql);
if ($statement === false) {
die(print_r($db->errorInfo(), true));
}
Here we take only the fields of $_POST that match the columns we want to insert.
$param_values = array_intersect_key($_POST, array_flip($columns));
And pass that array to execute(). Again, check for error return status.
$status = $statement->execute($param_values);
if ($status === false) {
die(print_r($statement->errorInfo(), true));
}
I have a php function getContactList():
$res = getContactList(trim($_POST['username']), trim($_POST['password']));
which returns this array:
$contactList[] = array('name' => $name, 'email' =>$email);
I need to store the contents of this array into a MySQL database.
Somehow can i store the entire contents of the array in the database at one go ??
The number of array items will be more than 500 at each go , so i wanna avoid the usual looping practice and calling the "Insert" statement in the for loop as this will need a long time to execute.
Note: I need to store the results in separate columns - One for Name and another for Email. With 500 items in that array I need to have 500 rows inserted - one Name-Email pair per row.
$values = array();
// the above array stores strings such as:
// ('username', 'user#domain.com')
// ('o\'brien', 'baaz#domain.com')
// etc
foreach($contactList as $i => $contact) {
$values[] = sprintf(
"('%s', '%s')",
mysql_real_escape_string($contact['name'], $an_open_mysql_connection_identifier),
mysql_real_escape_string($contact['email'], $an_open_mysql_connection_identifier)
);
}
$query = sprintf(
"INSERT INTO that_table(name, email) VALUES %s",
implode(",", $values)
);
If you are trying to insert many rows, i.e. run the same query many times, use a prepared statement.
Using PDO, you can do this:
// prepare statement
$stmt = $dbh->prepare("INSERT INTO contacts (email, name) VALUES (:email, :name);");
// execute it a few times
foreach($contactList as $contact) {
$stmt->bindValue(':email', $contact['email'], PDO::PARAM_STR);
$stmt->bindValue(':name', $contact['name'], PDO::PARAM_STR);
$stmt->execute();
}
PDO will also take care of proper string escaping.
use the standard php serialize function
$serData_str = serialize($contactList);
then save it in the DB
after reading your data from DB simply unserialize it
$myData_arr = unserialize($serContactList);
In the loop you can create an insert statement and execute it after the loop. the insert statement will include all content.
The statement would look like
INSERT INTO employee (name) VALUES ('Arrayelement[1]'),('Arrayelement[2]'), ('Arrayelement[3]'),('Arrayelement[4]');