Confused about adding array from post to database - php

I have a complicated array (at least it looks complicated to me). I have a form where you select a person, a start time and an end time. You can then add more people by clicking a + button. So I named the three select fields like "select_dancer[]" for an array.
When I print_r my results, it looks like this:
Array
(
[month_year] => 2011-11
[select_dancer] => Array
(
[0] => 1
[1] => 2
)
[time_from] => Array
(
[0] => 12:00pm
[1] => 1:00pm
)
[time_to] => Array
(
[0] => 12:30pm
[1] => 1:30pm
)
)
Basically, the key 0 is one person, and key 1 is another. Etc. I'm having trouble getting my head around adding this to the database. My table is basically: id, date, dancer, from, to. So I want it so I can "group" each key together and submit the values to the database.
If anyone could help me out, that would be great.

An easier approach to the field grouping would be something like this in your HTML
<input name="dancer[0][id]" ...
<input name="dancer[0][time_from]" ...
<input name="dancer[0][time_to]" ...
As each group is added, increment the number in the first square-brackets.
Your resulting $_POST array would then look like
Array
(
[month_year] => 2011-11
[dancer] => Array
(
[0] => Array
(
[id] => 1,
[time_from] => 12:00pm
[time_to] => 12.30pm
)
[1] => Array
(
[id] => 2
[time_from] => 1:00pm
[time_to] => 1:30pm
)
)
)
You can then iterate the $_POST['dancer'] array for each group of values, eg (very simplified)
foreach ($_POST['dancer'] as $dancer) {
if (!isset($dancer['id'], $dancer['time_from'], $dancer['time_to'])) {
throw new Exception('All fields are required');
}
$id = $dancer['id'];
$timeFrom = $dancer['time_from'];
$timeTo = $dancer['time_to'];
}

Try something like this:
for ($i = 0; $i < count($mydata["select_dancer"]); $i++)
{
$insert = "insert into mytable (date, dancer, from to) values ($mydata['month_year'], $mydata['select_dancer'][$i], $mydata['time_from'][$i], $mydata['time_to'][$i])";
do_sql_insert($insert);
}
With this, you're vulnerable to injection attacks and the chance that a particular dancer doesn't have a represented index in every sub-array. Go with what #Phil wrote if you can.

If each of element select_dancer, time_from, time_to has the same array size, you can easily check for any of that and do loop using it:
WARNING: UNTESTED CODE
foreach($post_array['select_dancer'] as $key => $value)
{
$sql = "INSERT INTO dance_table(date, dancer, from, to) ";
$sql .= "VALUES('{$wherever_you_got_the_date}', '{$value}',";
$sql .= "'" . $post_array['time_from'][$key] . "', ";
$sql .= "'" . $post_array['time_from'][$key] . "')";
}

foreach($_POST[select_dancer] as $key => $value) {
$sql = "insert into table set dancer=$value,from='{$_POST['time_from'][$key]}',to={$_POST['time_to'][$key]}';"
//execute the SQL ...
}
of course in real life got to deal will protecting against SQL injection etc, but the principle of accessing the arrays is the same

Related

PHP: Plot Data Points From MySQL on Graph (Google Graphs)

I'm trying to query our database to get all records that match the user defined query, and store the data in a formatted array. The problem is, I'm getting all of the records, but not really sure how to process the data appropriately. I've been working on this for a few days now and haven't made much head way after trying a variety of ideas. Hopefully, someone here will have some insight to share.
The code below executes the query and starts processing the returned data into the array:
$msg_vol = array();
$xy_coords = array();
$tweet_count = 1;
$query = "SELECT created_at, tweet_id FROM `tweets` WHERE tweet_text LIKE '%{$safe_q}%' AND created_at < now() - 300";
$tweets = mysqli_query($db, $query);
confirm_query($tweets);
while ($tweet = mysqli_fetch_assoc($tweets)) {
$created_at = $tweet['created_at'];
$timestamp = strtotime($created_at);
$created_at_no_seconds = date('Y-m-d H:i', $timestamp);
if(!in_array($created_at_no_seconds, $xy_coords)) {
$created_at = $tweet['created_at'];
$timestamp = strtotime($created_at);
$created_at_no_seconds = date('Y-m-d H:i', $timestamp);
if(!in_array($created_at_no_seconds, $xy_coords)) {
$xy_coords = array(0 => $created_at_no_seconds, array('tweet_count' => $tweet_count, 'retweets' => 0));
} else {
// $created_at_no_seconds exists in array
// update array
$msg_vol[$created_at_no_seconds] = array('tweet_count' => $tweet_count++, 'retweets' => 0);
}
}
return $msg_vol;
I'm reformatting the $created_at to the minute as, for the time being, I'm only interested in the data for the last 5 minutes (300 seconds) and want each minute separated out into it's own associative array. The $created_at_no_seconds variable can potentially contain duplicate entries to be added in the array. So, I've toyed with in_array() to try and check if it exists and only add it to the array if it does not. I didn't have much luck with this yet.
A print_r($msg_vol) provides the following output (which is slowly getting closer to the desired output):
[0] => Array
(
[created_at] => 2013-12-15 19:09
[tweet_count] => 1
[retweets] => 0
)
[2013-12-15 19:09] => Array
(
[tweet_count] => 11
[retweets] => 0
)
[1] => Array
(
[created_at] => 2013-12-15 19:09
[tweet_count] => 1
[retweets] => 0
...
[12] => Array
(
[created_at] => 2013-12-15 19:10
[0] => Array
(
[tweet_count] => 12
[retweets] => 0
)
)
[2013-12-15 19:10] => Array
(
[tweet_count] => 20
[retweets] => 0
)
[13] => Array
(
[created_at] => 2013-12-15 19:10
[0] => Array
(
[tweet_count] => 12
[retweets] => 0
)
)
...
(I'm not processing the retweets at the moment, so I'm simply adding a 0 to the retweets array as a placeholder).
I'm trying to format it so that in one array, it contains the unique date (down to the minute) where the values for tweet_count is stored within it. The above example with the date as the associative key, and the $k => $v inside is what I'm trying to achieve. But, when I keep getting the array populated with [0], [1]. [12], [13], etc.
Am I even close? This has been quite the rabbit hole... And, it's starting to become a dark and lonely place. :(
instead of using array push like this
array_push($msg_vol, $xy_coords);
why not try
$array[] = $xy_coords;
With regards the duplicates why not use SELECT DISTINCT in your mysql query?
I was able to solve the problem by optimizing the query (Thank you #php)!
$query = "SELECT DATE_FORMAT(created_at, '%Y-%d-%m %H:%i'),";
$query .= " COUNT(tweet_id), 0 FROM `tweets`";
$query .= " WHERE tweet_text LIKE '%{$safe_q}%'" ;
$query .= " AND created_at < now() - 300";
$query .= " GROUP BY DATE_FORMAT(created_at, '%Y-%d-%m %H:%i')";
$tweets = mysqli_query($db, $query);
confirm_query($tweets);
while ($tweet = mysqli_fetch_assoc($tweets)) {
echo '<pre>';
print_r($tweet); exit;
echo '</pre>';
}
Make use of MySQL functions. They are a life (and, hair) saver!

merge two arrays with numeric keys for values of associative array to insert in MySQL in multiple rows

I'm getting two arrays $post_img & $post_sort resulting:
Array
(
[0] => test1.jpg
[1] => test2.jpg
[2] => test3.jpg
)
Array
(
[0] => 3
[1] => 1
[2] => 2
)
I'd like to merge them like:
Array
(
[Image] => Array
(
[0] => test1.jpg
[1] => test2.jpg
[2] => test3.jpg
)
[Sort] => Array
(
[0] => 3
[1] => 1
[2] => 2
)
)
Because I think its the best way to insert them into my Database each entry in one row like:
ID | Image | Sort
1 test1.jpg 3
2 test2.jpg 1
3 test3.jpg 2
The point is that I think this should be possible with only one query.
I had different tries but none of them ended up good.
Using a multiple iterator
$mi = new MultipleIterator();
$mi->attachIterator(new ArrayIterator($post_img));
$mi->attachIterator(new ArrayIterator($post_sort));
foreach ( $mi as $value ) {
list($filename, $sortOrder) = $value;
echo $filename , ' => ' , $sortOrder , '<br />';
}
might make it easier to process both arrays at the same time for your database inserts
Use array:
$newarray = array('Image' => $post_img, 'Sort' => $post_sort);
For adding the data to your table, you can go with your original arrays:
$sql = "INSERT INTO tablename SET Image=:image, Sort=:sort";
$dbImgInsert = $db->prepare($sql); // preparing sql for insert, using parameters
$c = count($post_img)-1;
for ($i=0;$i<=$c;$i++;) { // looping through the arrays
$dbImgInsert->execute(array( // inserting the data into the prepared query and into the db
'image' => $post_img[$i],
'sort' => $post_sort[$i]
));
} // for
The above example assumes you are using MySQL with PDO.
To create a single INSERT-statement the classic way, go:
$sql="";
$c = count($post_img)-1;
for ($i=0;$i<=$c;$i++;) { // looping through the arrays
$sql.="('{$post_img[$i]}', '{$post_sort[$i]}'), ";
}
$sql ="INSERT INTO tablename (Image, Sort) VALUES " . trim($sql,',');
There is no point merging the arrays, you can just do a SQL statement like so:
INSERT INTO tbl (Image, Sort) VALUES
($post_img[0], $post_sort[0]),
($post_img[1], $post_sort[1]),
($post_img[2], $post_sort[2]),
($post_img[3], $post_sort[3])
The latter half of that query can be generated using a loop of some sort.

Update mysql table with an array

I've got table: platforms
Inside this table columns: 1. first_scan_date, 2. next_scan_date 3. scan_frequency
Now, I've got such array from the web based formular:
Array
(
[scan_freq1] => Array
(
[0] => 0
[1] => 0
[2] => 0
[3] => 0
)
[first_scan_date1] => Array
(
[0] => 0000-00-00
[1] => 0000-00-00
[2] => 0000-00-00
[3] => 0000-00-00
)
[next_scan_date1] => Array
(
[0] =>
[1] =>
[2] =>
[3] =>
)
)
How can I update it in database using things that came from array in PHP? I guess I need smth like foreach, but have no clue...
UPDATE platforms (first_scan_date,next_scan_date,scan_frequency) VALUES (?,?,?)...
Help?
I would loop through the array to prepare a string to insert in a single query like this:
$sql = "INSERT INTO table (first_scan_date,next_scan_date,scan_frequency)
VALUES ('0000-00-00','0000-00-00',1),('0000-00-00','0000-00-00',1),('0000-00-00','0000-00-00',1)
ON DUPLICATE KEY UPDATE first_scan_date=VALUES(first_scan_date),next_scan_date=VALUES(next_scan_date),scan_frequency=VALUES(scan_frequency);";
You could do something like this:
$freq = $arr['scan_freq1'];
$date1 = $arr['first_scan_date1'];
$date2 = $arr['next_scan_date1'];
foreach ($date1 as $key => $value){
$row[] = "('".$value."','".$date2[$key]."',".$freq[$key].")";
}
$list = implode(',', $row);
$sql = "INSERT INTO table (first_scan_date,next_scan_date,scan_frequency)
VALUES ".$list."
ON DUPLICATE KEY UPDATE first_scan_date=VALUES(first_scan_date),next_scan_date=VALUES(next_scan_date),scan_frequency=VALUES(scan_frequency);";
Try below way
$cnt = count($arr['scan_freq1']);
for($i=0;$i<$cnt;$i++){
echo $arr['scan_freq1'][$i];
echo $arr['first_scan_date1'][$i];
echo $arr['next_scan_date1'][$i];
//now you have three values make query and update into db
$db->prepare(
"UPDATE `platforms` SET `first_scan_date`=?, `next_scan_date`=?,
`scan_frequency`= ? WHERE platformtype='os'"
)->execute(array($arr['first_scan_date1'][$i],$arr['next_scan_date1'][$i],$arr['scan_freq1'][$i]));
}
this may be late but may help someone in the now or the future i believe here is the shortest way to achieve this
public function update($table,$values,$where_clause)
{
foreach ($values as $key => $val)
{
$valstr[] = $key." = '$val'";
}
$update_query = 'UPDATE '.$table.' SET '.implode(', ', $valstr)
." WHERE ".$where_clause;
return $update_query;
}
found this in one of codeigniters core files it simply loops through all values
stores them in an array then converts the array into a string and adds it to the query and the where clause comes last..i hope this helps someone

PHP Array insert into MySQL table as individual rows

I am trying to insert multiple rows in a MySQL table from PHP arrays. I managed with with help of other members to get set of values in a pair of brackets but when i try to insert this i get "Error: Column count doesn't match value count at row 1" I donot know where am i going wrong. my codes are as below: (The number of values i get vary according to user input)
$docno1=array();
$serialno = array();
$acc_name = array();
$debit = array();
$credit = array();
for ($i=1;$i<=$rowcount;$i++)
{
//echo 'Accountname'.$i.' :'.($_GET['accname'.$i]).'<br>';
$docno1 [] = ($_GET['docno']);
array_unshift($docno1,"");
unset($docno1[0]);
$serialno [] = $i;
array_unshift($serialno,"");
unset($serialno[0]);
$acc_name[] = ($_GET['accname'.$i]);
array_unshift($acc_name,"");
unset($acc_name[0]);
$debit[] = ($_GET['DrAmount'.$i]);
array_unshift($debit,"");
unset($debit[0]);
$credit[] = ($_GET['CrAmount'.$i]);
array_unshift($credit,"");
unset($credit[0]);
}
$sum_dr = array_sum ($debit);
$sum_cr = array_sum ($credit);
echo ' values of $multi<br>';
$multi = array(
($docno1),
($serialno), //Array for a row of fields
($acc_name),
($debit),
($credit),
($docno1)
);
print_r($multi);
$new = array();
foreach($multi as $key=>$value) {
$new[] = "'".implode("','", $value)."'";
}
echo '<br>Values of $new <br>';
print_r($new);
$query = "(".implode("), (",$new).")";
echo $query.'<br>';
mysql_query("INSERT INTO docitems (`docno`,`itemno`,`accountname`,`debit`,`credit`, `picrefno`) VALUES ".$query.";") or die('Error: ' . mysql_error());
echo "Inserted successfully";
die;
The results i get are :
values of $multi
Array
(
[0] => Array
(
[1] => 3434
[2] => 3434
)
[1] => Array
(
[1] => 1
[2] => 2
)
[2] => Array
(
[1] => Lemon
[2] => Kidney Beans
)
[3] => Array
(
[1] => 20
[2] => 10
)
[4] => Array
(
[1] => 0
[2] => 0
)
[5] => Array
(
[1] => 3434
[2] => 3434
)
)
Values of $new
Array
(
[0] => '3434','3434'
[1] => '1','2'
[2] => 'Lemon','Kidney Beans'
[3] => '20','10'
[4] => '0','0'
[5] => '3434','3434'
)
('3434','3434'), ('1','2'), ('Lemon','Kidney Beans'), ('20','10'), ('0','0'), ('3434','3434')
Error: Column count doesn't match value count at row 1
mysql_query("INSERT INTO docitems (`docno`,`itemno`,`accountname`,`debit`,`credit`, `picrefno`) VALUES ".$query.";") or die('Error: ' . mysql_error());
You are trying to insert something into 6 fields, so that $query string must have 6 values in it, or you get this error.
You have a lot of $query's that are 2 values. And that's not 6
It looks to me as if you are mapping your array the wrong way round. You're trying to add two records with six fields each, but what you're actually putting into the SQL statement are six records with two fields each.
This is why MySQL is complaining -- because you've told it you want to update six fields, but in each of the records you've given it, you've only specified two fields.
You need to build your array differently.
I assume that $docno1, $serialno, $acc_name, $debit and $credit will always all have the same number of array elements (it appears from your code that you are assuming this, so I'll follow you in your assumption).
In that case, you need to build your array something like this:
$multi = array();
foreach($docno1 as $key=>value) {
$multi[] = array(
$docno1[$key],
$serialno[$key], //Array for a row of fields
$acc_name[$key],
$debit[$key],
$credit[$key],
$docno1[$key])
}
Replace the block in your code where you set $multi with this, and your program should work.
Look at what print_r($multi) looks like now, and you'll see the difference.
(note, there are more efficient ways of writing your whole program than this, but I've focused on giving you a drop-in replacement for this specific bit, to help show you where you were going wrong, rather than simply rewriting the whole program for you)
Hope this helps.
If the error is occurring when trying to insert a row to your table, try specifying the list of fields, in the insert query -- this way, the number of data in the values clause will match the number of expected columns.
Else, MySQL expects six columns : it expects the specific inserts -- for which you didn't specify a value.

Inserting values from multidim. array using PDO takes a long time. Is there a better way?

I got an array of 650 rows. Inserting this using PDO takes between 10-15 seconds on my local computer.
That's very slow. Is this because of disk read/write? Or could it be something else?
This is my array (first 4 rows):
Array
(
[0] => Array
(
[0] => 3
[1] => 1
)
[1] => Array
(
[0] => 3
[1] => 2
)
[2] => Array
(
[0] => 3
[1] => 5
)
[3] => Array
(
[0] => 8
[1] => 1
)
)
And this is my code:
$stmt = $this->db->prepare("INSERT INTO sl_link_store_category (item_a_ID, item_b_ID) VALUES (:item_a_ID, :item_b_ID)");
foreach($my_array as $row) {
$stmt->execute(array(':item_a_ID' => $row[0], ':item_b_ID' => $row[1]));
}
SOLUTION
For those who is wondering, her eis my solution for inserting multiple rows
using only one $stmt->execute:
$input_arr; // This array one has lots of values
$sql = "INSERT INTO sl_link_store_category (field_a, field_b) VALUES ";
$i = 0;
// I create the query string with unique prepared values
// I could probably have used a for loop since I'm not using any
// values from $row
foreach($input_arr as $row) {
$i++;
$sql .= "(:field_a_$i, :field_a_$i), ";
}
// Remove the last comma (and white space at the end)
$sql = substr(trim($sql), 0, -1);
$stmt = $this->db->prepare($sql);
// I need to create a new associative array with field name
// matching the prepared values in the SQL statement.
$i = 0;
$arr = array();
foreach($input_arr as $row) {
$i++;
$arr[":field_a_$i"] = $row[0];
$arr[":field_b_$i"] = $row[1];
}
$stmt->execute($arr);
}
The reason it might be that slow can vary based on alot of factors.
Consider using one query to insert multiple records PDO Prepared Inserts multiple rows in single query

Categories