How to insert multiple items using foreach loop - php

I've been trying to insert multiply items using foreach loop in php and mysql. When i insert its insert null values. any ideas as to what i should fix?
$itemNo = $statement->fetchColumn();
$item_name = ($_POST["item_name"]);
$item_price = ($_POST["item_price"]);
$item_quantity = ($_POST["item_quantity"]);
$item_total = ($_POST["item_total"]);
$statement = $connect->prepare("
INSERT INTO product
( `item_no`,`item_name`, `item_price`, `item_quantity`, `item_total`)
VALUES ('$itemNo','$item_name','$item_price','$item_quantity','$item_total')
");
foreach($_POST["item_name"] as $subscription){
$statement->execute(
array(
':itemNo' => $itemNo,
':item_name ' => trim($_POST["item_name"]),
':item_price' => trim($_POST["item_price"]),
':item_quantity' => trim($_POST["item_quantity"]),
':item_total' => trim($_POST["item_total"])
)
);
}

You need to put placeholders in the query, not variables, to match the parameters in the call to execute().
$statement = $connect->prepare("
INSERT INTO product
( `item_no`,`item_name`, `item_price`, `item_quantity`, `item_total`)
VALUES (:itemNo,:item_name,:item_price,:item_quantity,:item_total)
");
And if $_POST['item_name'] is an array, you can't use trim($_POST['item_name']) as a value. The argument to trim() has to be a string, not an array. If these post variables are all arrays, you need to index them.
foreach ($item_name as $index => $subscription) {
$statement->execute(
array(
':itemNo' => $itemNo,
':item_name ' => trim($subscription),
':item_price' => trim($item_price[$index]),
':item_quantity' => trim($item_quantity[$index]),
':item_total' => trim($item_total[$index])
)
);
}

Related

PHP convert columns to query

I have a table on the frontend, where the user can choose what types of columns he wants.
After submitting the form I get the array with selected columns.
For instance the user select following columns:
$columns = ["campaign_start_time", "campiagn_end_time", "campaign_id", "campaign_budget", "adset_name", "ad_name"]
Now I have to make the request to the facebook api, but facebook api only request query in form:
$query = "campaign{start_time, end_time, id, budget}, adset{name}, ad{name}"
Here is my question, what is the best way to convert $columns to $query in PHP language?
If you can construct your submitted data to be in this form:
Array
(
[campaign] => Array
(
[0] => start_time
[1] => end_time
[2] => id
[3] => budget
)
[adset] => Array
(
[0] => name
)
[ad] => Array
(
[0] => name
)
)
Maybe using inputs or other constructs such as:
name="campaign[]" value="start_time"
name="campaign[]" value="end_time"
Then looping and building the query with the keys and values will do it:
foreach($columns as $key => $val) {
$query[] = $key . '{' . implode(',', $val) . '}';
}
$query = implode(',', $query);
Otherwise you'll need to parse it to get what you need first, then execute the loop above using $result instead:
foreach($columns as $val) {
preg_match('/^([^_]+)_(.*)/', $val, $match);
$result[$match[1]][] = $match[2];
}
This solution splits apart the values based on underscores and then joins them back together as nested values based on the category/key. Note that this doesn't check for items that don't have a "prefix".
<?php
$columns = ["campaign_start_time", "campaign_end_time", "campaign_id", "campaign_budget", "adset_name", "ad_name"];
$criteria = [];
foreach( $columns as $column ){
$pieces = explode('_',$column);
$category = array_shift($pieces);
if( !isset($criteria[$category]) ){
$criteria[$category] = [];
}
$criteria[$category][] = implode('_', $pieces);
}
$queryPieces = [];
foreach($criteria as $category => $values){
$queryPieces[] = $category.'{'.implode(', ', $values).'}';
}
$query = implode(', ', $queryPieces);

Parse php array to make insert statement

Hi I have an array like this:
$datas =
[
'name_1'=>'John',
'name_2' =>'Mickey',
'settings_1' => 'Settings 1',
'settings_2' => 'Settings 2'
]
foreach($datas as $data){
//get items here...
}
How to pair or parse those items to make insert statement like this:
INSERT INTO table (name, settings)VALUES('John','Settings 1');
INSERT INTO table (name, settings)VALUES('Mickey','Settings 2');
Any idea? Thanks in advance.
This code could be usefull for creating array of arrays. Considering array keys will be name_x and settings_x
foreach($datas as $key=>$value){
// explode each key of the array
$keys = explode('_',$key);
$name = 'name_'.$keys[1];
$settings = 'settings_'.$keys[1];
// to generate array
$new_array[$keys[1]]=array('name'=>$datas[$name], 'settings'=>$datas[$settings]);
}
print_r($new_array);
Loop the $new_array for insert query.
Output :
Array
(
[1] => Array
(
[name] => John
[settings] => Settings 1
)
[2] => Array
(
[name] => Mickey
[settings] => Settings 2
)
)
$datas =
[
'name_1'=>'John',
'name_2' =>'Mickey',
'settings_1' => 'Settings 1',
'settings_2' => 'Settings 2'
];
$results = [];
foreach($datas as $index=>$data){
//create an array out of $index breaking it at the '_'
//so array will be $parts = [0=>'name', 1=>'1'];
$parts = explode('_', $index);
//'name_1'=>'John' = $results[1]['name'] = 'John';
$results[$parts[1]][$parts[0]] = $data;
}
//batch insert new formed array
//INSERT INTO tbl_name (name, settings) VALUES $results;
Check this, you must do some intermediate steps. Comments on code!!
$datas =
[
'name_1'=>'John',
'name_2' =>'Mickey',
'settings_1' => 'Settings 1',
'settings_2' => 'Settings 2'
];
$data_final = [];
foreach($datas as $key=>$value){
$keyX = preg_replace('/^(.+)_(\d+)$/', '$1', $key);// get the "type" (name, setting)
$keyY = preg_replace('/^(.+)_(\d+)$/', '$2', $key);// get the "index" (_1, _2 without "_")
$data_final[$keyY][$keyX] = $value; // put in result
}
// make queries
$sql = [];
foreach($data_final as $datas){
$fields = implode(", ", array_keys($datas)); //implode the keys to sql fields
$values = implode(", ", array_map(function($a){return "'$a'";}, array_values($datas)));//implode values to sql values adding ''. WARNING: This not escape values. Use escape string function on mysqli obj or PDO to the right escape
$sql[] = "INSERT INTO table ($fields) VALUES ($values);"; // populate query
}
$sql = implode("\n", $sql); // implode with new line
print_r($sql); //results
IMPORTANT:
You must have the right syntax "field_number" to respect the procedure
You can use even with one or more of two fields per record
You can use any field name, always respecting the "field_number" syntax
DEMO HERE

Inserting multiple arrays into a mysql database

Each input->post is a key/value array. Each value inside of each array matches up to the rest of the array values. So the first row in the database insertion will be all of the data from all of the array's key 0. The second will be 1 and so on and so on. How would I take all of the data from the post arrays and insert them into the database using this method?
$selected_size = $this->input->post('selected_size');
$product_id = $this->input->post('product_id');
$product_name = $this->input->post('product_name');
$product_color = $this->input->post('product_color');
$cookie_id = $this->input->cookie("cookie_id");
$q1 = $this->db->query("SELECT * FROM default_cart_temp
WHERE cookie_id = '$cookie_id'
AND is_paid = 'No'");
if ($q1->num_rows() > 0) {
} else {
print_r($selected_size);
/*$data = array('selected_size' => $selected_size,
'product_id' => $product_id,
'product_name' => $product_name,
'product_color' => $product_color);
$this->db->insert('mytable', $data);*/
}
Assuming your insert() method takes an associative array and then builds and executes the insert statement:
foreach($product_id as $key => $value)
{
$data = array(
'selected_size' => $selected_size[$key],
'product_id' => $value,
'product_name' => $product_name[$key],
'product_color' => $product_color[$key]
);
$this->db->insert('mytable', $data);
}
By using a foreach on one of the arrays and obtaining the key on each iteration, you can use the same key variable to access the corresponding element in each other array.

Using a loop to perform multiple SQL inserts using Codeigniter/Activerecord

I have an array that looking like this:
Array
(
[currency] => GBP
[shipping] => 3.5
[tax] => 0
[taxRate] => 0
[itemCount] => 3
[item_name_1] => Proletarian Sparrow
[item_quantity_1] => 2
[item_price_1] => 75
[item_name_2] => Guillemot Colony
[item_quantity_2] => 5
[item_price_2] => 20
[item_name_3] => Dandelion Clock
[item_quantity_3] => 2
[item_price_3] => 50
)
I'm trying to use a loop to extract the individual item details and insert a row in a database for each one. I'm using Codeigniter.
My model looks like this:
public function set_order($cust_id, $order_data)
{
// Breaks up order information and creates a new row in the pn_orders tables for each item
// Get the last row in the orders table so we can work out the next order_id
$this->db->order_by('order_id', 'desc');
$this->db->limit(1);
$query = $this->db->get('pn_orders');
$row = $query->row_array();
// If the resulting array is empty, there are no orders so we can set the order_id to 1. If there is already an order_id, just add 1 to it.
if (empty($row)) {
$order_id = 1;
} else {
$order_id = $row['order_id'] + 1;
}
//echo "<pre>";
//print_r($order_data);
//echo "</pre>";
// The delivery message input has a placeholder. if the user's input is different to this, assign it to $delivery_message.
if ($this->input->post('delivery_message') == "e.g. if out, leave in porch") {
$delivery_message = NULL;
} else {
$delivery_message = $this->input->post('delivery_message');
}
// Set today's date for insertion into the DB
$date = date('Y-m-d');
// The order information is clumped together in a single array. We have to split out single items by looping through the array before inserting them into the DB.
for ($i = 1; $i <= $order_data['itemCount']; $i++) {
$item = array(
'order_id' => $order_id,
'cust_id' => $cust_id,
'date_ordered' => $date,
'item_name' => $order_data["item_name_{$i}"],
'item_quantity' => $order_data["item_quantity_{$i}"],
'item_price' => $order_data["item_price_{$i}"],
'payment_method' => $_POST['payment_method'],
'delivery_message' => $delivery_message
);
$this->db->insert('pn_orders', $item);
}
}
Everything seems to be in place, however, only 1 row is ever inserted and I can't work out why. It seems very simple.
Is it something to do with the Activerecord pattern?
Thanks.
First print out the array to see if the array structure is correct or not. If its Okay then just use insert_batch like this:
for ($i = 1; $i <= $order_data['itemCount']; $i++) {
$items[] = array(
'order_id' => $order_id,
'cust_id' => $cust_id,
'date_ordered' => $date,
'item_name' => $order_data["item_name_{$i}"],
'item_quantity' => $order_data["item_quantity_{$i}"],
'item_price' => $order_data["item_price_{$i}"],
'payment_method' => $_POST['payment_method'],
'delivery_message' => $delivery_message
);
}
//echo "<pre>";print_r($item);echo "</pre>";die; uncomment to see the array structure
$this->db->insert_batch('pn_orders', $items);

Algorithm to dynamically merge arrays [duplicate]

This question already has answers here:
Two arrays in foreach loop
(24 answers)
Closed 6 months ago.
I'm trying to create a INSERT statement for every row in a PHPExcel object. As I've struggled to iterate across the column (ie. go B1 C1 D1, get the values, and put them into an array), I've opted to get all the values for each column and put them into a multi-dimensional array that looks like this:
Array
(
[foo] => Array
(
[0] => 250
[1] => 247
[2] => 279
[3] => 249
)
[bar] => Array
(
[0] => AM PROV
[1] => AM PROV
[2] => AM PENS
[3] => AM PROV
)
[schoo] => Array
(
[0] => xxxx
[1] => yyy
[2] => zzz
[3] => aaa
)
)
I want to merge each of the arrays so that all the data at index 0 is in one array, etc. I've built a generic tool to allow you to select the columns you want from an uploaded spreadsheet. It needs to first merge the column data into a single array and then it should generate INSERT statements for each of the arrays. So the final deliverable is this:
INSERT INTO (foo, bar, schoo) VALUES (250, "AM PROV", "xxxx");
All help appreciated.
UPDATE: Hey all, thank you very much for your answers. I finally managed to get it working using row and cell iterators as per Mark's suggestion and it's working. I have a separate issue with it now, but I think it's something I can solve. Thanks again.
<?php
$uberArray = array(
"foo" => array(
0 => 250,
1 => 247,
2 => 279,
3 => 249,
),
"bar" => array(
0 => "AM PROV",
1 => "AM PROV",
2 => "AM PENS",
3 => "AM PROV",
),
"schoo" => array(
0 => "xxxx",
1 => "yyy",
2 => "zzz",
3 => "aaa",
)
);
$yourMysqlLink = mysql_connect('localhost', 'user', 'pass');
mysql_query('SET NAMES utf8'); // Adjust according to your encoding
$colNames = array_keys($uberArray);
$stringCols = array('bar', 'schoo');
$sqlInsertStr = 'INSERT INTO `your_table` (`'.implode('`, `', $colNames)."`) VALUES \n";
$rows = array();
// Not really for iterating the first array, we just need a loop
foreach ($uberArray[$colNames[0]] as $k => $v) {
$vals = array();
foreach ($colNames as $v2) {
$val = $uberArray[$v2][$k];
if (in_array($v2, $stringCols)) {
$val = "'".mysql_real_escape_string($val, $yourMysqlLink)."'";
}
$vals[] = $val;
}
$rows[] = "\t(".implode(', ', $vals).")";
}
$sqlInsertStr .= implode(",\n", $rows).';';
echo '<pre style="clear:both;">'.$sqlInsertStr.'</pre>'; ;
Note that you may need to do a few adjustments for performance reasons, if $uberArray is big (e.g. splitting the insert string into chunks). Or you can convert the data to CSV and use MySQL LOAD DATA INFILE method, which is real fast.
Not sure if this is what you were after but...
<?php
# Given this array
$arrays = array(
'foo' => array(
0 => 250,
1 => 247,
2 => 279,
3 => 249
),
'bar' => array(
0 => 'AM PROV',
1 => 'AM PROV',
2 => 'AM PENS',
3 => 'AM PROV'
),
'schoo' => array(
0 => 'xxxx',
1 => 'yyy',
2 => 'zzz',
3 => 'aaa'
)
);
# This code generates...
$fields = array();
$inserts = array();
foreach ($arrays as $k => $v) {
$fields[] = $k;
}
for ($i = 0; $i < count($arrays[$fields[0]]); $i++) {
$vals = array();
foreach ($fields as $field) {
$vals[] = $arrays[$field][$i];
}
$inserts[] = 'INSERT INTO (' . implode(',', $fields) . ') VALUES ("' . implode('","', $vals) . '")';
}
# This array
/* $inserts = array(
'INSERT INTO (foo, bar, schoo) VALUES ("250", "AM PROV", "xxxx")',
'INSERT INTO (foo, bar, schoo) VALUES ("247", "AM PROV", "yyy")',
'INSERT INTO (foo, bar, schoo) VALUES ("279", "AM PENS", "zzz")',
'INSERT INTO (foo, bar, schoo) VALUES ("249", "AM PROV", "aaa")'
); */
var_dump($inserts);
Edit: Though I think you're missing a table name from your INSERT statements.
Edit2: You could shorten the code using array_keys like Frosty Z does and skip the first foreach.
$inputArray = array('a' => array(1, 2, 3), 'b' => array("X'", 'Y', 'Z'));
$finalArray = array();
// build array with appropriate data rows
$finalIndex = 0;
foreach($inputArray as $key => $row)
{
foreach($row as $value)
$finalArray[$finalIndex][] = $value;
$finalIndex++;
}
// format it as SQL insert queries
$fields = array_keys($inputArray);
foreach($finalArray as $row)
{
echo "INSERT INTO table (".implode(", ", $fields).") "
. " VALUES (".implode(", ", array_map("format_data", $row)).");\n";
}
function format_data($value)
{
// assuming you're using MySQL. Replace the escape function by
// the appropriate one
if (is_string($value))
return "'".mysql_real_escape_string($value)."'";
else
return $value;
}
You can use one of those strange spl iterators for this :)
$iter = new MultipleIterator(MultipleIterator::MIT_KEYS_ASSOC);
foreach ($uberArray as $colName => $colValues) {
$iter->attachIterator(new ArrayIterator($colValues), $colName);
}
foreach ($iter as $vals) {
print_r($vals);
//or $pdoStmt->execute($vals);
}
But really, a simple for loop is the tool to use here.
I see no reason to merge the array unless you feel like wasting memory. You've already probably made a copy of the data. This just inserts the data row by row.
$data = array('foo' => array(...), ... );
$fields = array('foo', 'bar', 'schoo');
$c = count($data[$fields[0]));
$base_sql = 'INSERT INTO tbl ('.implode(',', $fields).') VALUES ';
for ($i = 0; $i < $c; ++$i)
{
$row_data = array();
foreach ($fields as $field)
$row_data[] = "'".escape_func($data[$field][$i])."'";
$sql = $base_sql . '(' . implode(',', $row_data). ')';
db_query($sql);
}
I would actually use prepared statements.
And you really should try to figure out how to iterate through the original dataset in one pass.

Categories