Multidimensional arrays to insert for one row - php

I have three arrays that look like this:
ingredientQTY is the first input box in each row, measurements is the select/dropdown in each row, and ingredientsNAME is the last input box in each row. As you can see, there can be infinite numbers of ingredientQTY's, ingredientNAME's, and measurements.
When I send them to my php script, the data is in arrays like:
IngredientQTY
(
[0] => 5 //The first row
[1] => 5 //The next rows value
)
Measurements
(
[0] => Bunch //The first row
[1] => Bunch //The next rows value
)
IngredientName
(
[0] => 5 //The first row
[1] => 5 //The next rows value
)
I'm trying to upload them to a table called ingredients that has 3 columns: ingredientNAME, ingredientQTY, and measurements.
In my php script, I'm combining them into a multidimensional array, which is assigned to $ingredientsROW:
foreach($_POST as $key => $value) {
$value = $this->input->post($key);
$ingredientQTY = $this->input->post('ingredientQTY');
$measurements = $this->input->post('measurements');
$ingredientNAME = $this->input->post('ingredientNAME');
$ingredientsROW[] = array($ingredientQTY, $measurements, $ingredientNAME);
break;
}
My question is: How can I get group all the first row of form elements (which means the first ingredientQTY, the first measurements dropdown and the first ingredientNAME and insert them into a row?
The only way I could think of is to have one insert where I insert ingredientQTY, then look up the id of the row I just inserted and use two mysql updates to enter for the same row, but I'm pretty sure there is more efficient ways of going about this.

Would something like this work?
foreach($_POST['IngredientQTY'] as $index=>$qty)
mysql_query("insert into ingredients ".
"set IngredientQTY='".addslashes($qty)."'".
", measurements ='".addslashes($_POST['measurements'][$index])."'".
", ingredientNAME ='".addslashes($_POST['ingredientNAME'][$index])."');

Iterate through the data and create an array like this:
for ($i = 0, $count = count($ingredientQTY); $i < $count; $i++) {
$rows[] = array(
'QTY' => $ingredientQTY[$i],
'measurement' => $measurements[$i],
'name' => $ingredientNAME[$i]
);
}
With this array you can create the insert quite easily and insert whole rows.

Related

multiple rows with one INSERT INTO

I am developing an administration panel for my site locally. I would need to insert multiple rows with a single INSERT INTO query.
Initially I transform the string saved with commas into an array and then I try with a foreach loop to insert but it doesn't work ...
$aa = explode(',', $data['recipe_ingredient']);
<!-- Result Array ( [0] => one element [1] => second element [2] => third element ) -->
foreach($aa as $entry) {
$this->db->query('INSERT INTO recipes_ingredient (recipe_id, recipe_ingredient_name)
VALUES (:last_id, :name)'); <-- :name contain "n" result
$this->db->bind(':last_id', $this->db->lastId());
$this->db->bind(':name', $entry);
if($this->db->execute()) {
return true;
} else {
return false;
}
}
Anyone have any suggestions?
Thank you

why i have NULL when saving data in database

I'm trying to save with foreach
here is what i get from my form
Array
(
[mulai] => 2016-08-28
[akhir] => 2016-08-31
[keterangan] => remarks
[nip] => Array
(
[0] => 1004384
[1] => 1602744
[2] => 1501039
)
)
and then here is my saving query.
$jumlahrange = $this->db->query("SELECT DATEDIFF(day,'".$mulai."','".$akhir."') AS diff")->row();
$totaldata = count($nip);
$skrg = $this->db->query("SELECT GETDATE() tgl")->row();
for($x = 0;$x<=$totaldata;$x++)
{
for($y=0;$y<$jumlahrange->diff;$y++){
$this->db->query("INSERT INTO attendance
(Nip,AttendanceDate,InTime,OutTime,AttendanceCode,RosterCode,LocationCode,Remarks,CreatedDate,CreatedBy,ModifiedDate,ModifiedBy)
values(
'".$nip[$x]."',DATEADD(DAY,".$y.",'".$mulai."'),'','','P3','','','".$keterangan."','".$skrg->tgl."','$niplogin','','')
");
}
}
i have no problem with my save but i have empty field like this in my table. In row 10,11,12 . That row should not exist right?.
I using SqlServer 2008 and Codeigniter . I know i can use insert_batch, but i want use this way.
in your line for($x = 0;$x<=$totaldata;$x++) i'm pretty sure you wanted to write < instead of <=
To overcome these kind of issues you can use foreach loop instead
foreach($resourcedata as $value){
//your code goes here and you will get all array elements sequentially in **$value** variable
}
This one is right at your fingertips. $nip[$x] is null. Error log or dump and die on the first loop $nip[$x] and see what it returns. If it is in fact not null, then it might be a data type problem (string vs int).

How to sort a multidimensional array of columns by a specific column in PHP?

I found on the PHP documentation the function "array_multisort" that is meant to sort an array "of columns". They provide one example where the user has an array of rows and then the user has to transform this array of rows into an array of columns. In my case the array is already set by columns, such as:
tablearray
{
['Employee_ID'] = {0 => row1, 1 => row2, 2 => row3, 3 => row4}
['First_Name'] = {0 => row1, 1 => row2, 2 => row3, 3 => row4}
['LastName'] = {0 => row1, 1 => row2, 2 => row3, 3 =>row4}
}
I want to sort by Employee_ID and I need all the other columns to follow the same order. I tried:
array_multisort($tablearray['Employee_ID'], SORT_ASC);
But it only sorts the first column (which becomes a mess). The array has more than 10 columns and it changes the column names depending on the search (the columns names are its keys).
On PHP's documentation for this function, the example provided shows that the after transforming the rows array into a columns array, we should use the original array as a third parameter to match the keys - I don't have the "original" array to do the match since I didn't transform anything.
Thank you.
Desired output, as suggested by one user:
Original:
array
{
['Employee_ID'] = (1002, 4508, 0002, 1112)
['Business_Unit'] = ('UER', 'ABC', 'XYZ', 'EER')
['LastName'] = ('Smith', 'Vicente', 'Simpson', 'Thompson')
}
Sorted by Employee ID:
array
{
['Employee_ID'] = (0002, 1002, 1112, 4508)
['Business_Unit'] = ('XYZ', 'UER', 'EER', 'ABC')
['LastName'] = ('Simpson','Smith', 'Thompson', 'Vicente')
}
--
My original array is a database query output:
Array
(
[0] => Array
(
[Employee_ID] => 0000
[Supervisor_ID] => 00000
[Location_Descr] => somewhere
[Start_Date] => 06/03/2002
[Service_Date] => 06/03/2002
[Rehire_Date] => 00/00/00
[Business_Unit] => YYYY
[Job_Title] => Manager
[Email] => email#example.com
[Dept_Desc] => bla bla bla
[Employee_Name_LF] => Last, First
[Supervisor_Name_LF] => Last, First
[Term_Date] => 00/00/00
[Preferred_Name] => Someone
[Source] => Sheet2
)
)
There a several more rows.
The main purpose is to show the results as an HTML table and to generate a CSV file. I already made those functions using the modified structure (the first that I posted). I thought it would be easier to deal with that structure... Indeed it was, but not for sorting unfortunately.
The array_multisort documentation (http://php.net/manual/en/function.array-multisort.php) suggests separating each column as an individual array.. However, as you can see I have several columns (and the user can select more or less to be shown before performing the query.. So I can't just list all of them on the statement).
I a willing to change everything just to make the code better to be worked with.
Ugly - would be a lot easier if you formatted the input tables.
$arr = array(
'Employee_ID' => array('1002', '4508', '0002', '1112'),
'Business_Unit' => array('UER', 'ABC', 'XYZ', 'EER'),
'LastName' => array('Smith', 'Vicente', 'Simpson', 'Thompson')
);
$employees = array();
foreach (range(0, sizeof($arr[current(array_keys($arr))]) - 1) as $k) {
$emp = array();
foreach ($arr as $col => $vals) {
$emp[$col] = $arr[$col][$k];
}
$employees[] = $emp;
}
$sort = array();
foreach ($employees as $k => $v) {
$sort[$k] = $v['Employee_ID'];
}
array_multisort($sort, SORT_ASC, $employees);
print_r($employees);
And to put back in the original format:
$arr_sorted = array();
foreach (array_keys($arr) as $col) {
$arr_sorted[$col] = array();
foreach ($employees as $emp) {
$arr_sorted[$col][] = $emp[$col];
}
}
print_r($arr_sorted);
Thank you for posting the extra details in your question, as they did help in understanding the intent of your question.Now, you didn't tell us how that table should look; If you want the employees one per row, or one per column. Which is kind of crucial to know. Normally one would have one employee per line, especially if this is to be exported to CVS. However, I have a suspicion that it's the latter you want. Otherwise you've gone about this in a very overly complicated manner.Point in case: Normal one-per-row layout:
<?php
$db = new PDO();
// Defining the fields we need here, to avoid having too long a string for the query.
$fields = "e.employee_id, e.first_name, e.lastname, u.business_unit, s.email";
// Do the sorting in the database itself. Not only is this faster, but it
// is also a lot easier to sort it exactly as you'd like.
// Note that I don't use prepared statements here, as there is no user-input.
$query = <<<outSQL
SELECT {$Fields} FROM `unit` AS u
INNER JOIN `employee` AS e ON e.employee_id = u.unit_id
INNER JOIN `employee` AS s ON s.employee_id = u.supervisor_id
ORDER BY e.`employee_id`
outSQL;
$data = $db->query($query);
// Creating a printf() template for the output, to make the code easier to maintain.
$rowTemplate = <<<outHTML
<tr>
<td>%1\$d</td>
<td>%2\$s</td>
<td>%3\$s</td>
</tr>
outHTML;
// Generate the table template, using placeholders for where the data will be added..
$tableTemplate = <<<outHTML
<table>
<thead>
<tr>
<th>ID</th>
<th>First name</th>
<th>Last name</th>
</tr>
</thead>
<tbody>
%s
</tbody>
</table>
outHTML;
// Regular table output, one employee per line.
$temp = '';
foreach ($data as $e) {
// hs() is a shortcut function to htmlspecialchars (), to prevent against XSS.
$temp .= sprintf($rowTemplate, $e['employee_id'], hs($e['first_name']), hs($e['lastname']));
}
// Add the rows to the table, so that you can echo the completed product wherever you need.
$employeeTable = sprintf($tableTemplate, $temp);
If you want to do it one per column, it becomes a bit more intricate. Though, still a bit easier than your first attempt. :)
Namely, something like this:
<?php
$db = new PDO();
// Defining the fields we need here, to avoid having too long a string for the query.
$fields = "employee_id, first_name, lastname";
// Do the sorting in the database itself. Not only is this faster, but it
// is also a lot easier to sort it exactly as you'd like.
// Note that I don't use prepared statements here, as there is no user-input.
$data = $db->query("SELECT {$Fields} FROM `employees` ORDER BY `employee_id`");
// We need to know how many columns we'll have. One per employee.
$columns = count ($data);
// Rows have a header in front of each line, and one td tag for each employee.
$rowTemplate = "\t\t<th>%s</th>\n".str_repeat("\t\t\t<td>%s</td>\n", $columns);
// Generate the table template, using placeholders for where the data will be added..
$tableTemplate = <<<outHTML
<table>
<tbody>
%s
</tbody>
</table>
outHTML;
// Reformat the array to give us the data per-column.
$temp = array ();
foreach ($data as $field => $e) {
// Since we've already sorted the data in the database we don't need to do any further sorting here.
// Also note that I'm doing the escaping here, seeing as this array will only be used for output.
$temp['Employee ID'][] = intval($e['employee_id']);
$temp['First name'][] = hs($e['first_name']);
$temp['Last name'][] = hs($e['lastname']);
}
// Now we do the same as in the above example.
$rows = '';
foreach ($temp as $label => $l) {
// We have the label as the first template variable to be added, so put it as the first element.
array_unshift($l, $label);
// Add the current row of items to the output, using the previously established template.
$rows = vprintf($rowTemplate, $l);
}
// Add the rows to the table, so that you can echo the completed product wherever you need.
$employeeTable = sprintf($tableTemplate, $temp);
PS: Haven't tested the code, but it should work.
I ran into his problem and after much angst found a really nice solution in the notes on the php manual page - I now have the following function which i use whenever I need to solve this type of problem.
function fnArrayOrderby(){
//function to sort a database type array of rows by the values in one or more column
//source http://php.net/manual/en/function.array-multisort.php - user notes
//example of use -> $sorted = fnArrayOrderby($data, 'volume', SORT_DESC, 'edition', SORT_ASC);
$args = func_get_args(); //Gets an array of the function's argument list (which can vary in length)
//echo "sorting ".$args[0]."<br>";
if (!isset($args[0])) { return;}
$data = array_shift($args); //Shift an element off the beginning of array
foreach ($args as $n => $field) {
if (is_string($field)) {
$tmp = array();
foreach ($data as $key => $row)
$tmp[$key] = $row[$field];
$args[$n] = $tmp;
}
}
$args[] = &$data;
call_user_func_array('array_multisort', $args);
return array_pop($args);
}

Assign Array Value to Variable and Insert into mysql using PHP

I am trying to save array value to variable so that I can insert that data/value into mysql using PHP for that I am using a pain taking long code so I want simple method to do it without writing it again and again.
Array shows data like this
Array
(
[0] => Array
(
[0] => a><p class="wp-caption-text">Pendant Heart Images</p></div>
[1] => a><p class="wp-caption-text">Pendant Heart Photos</p></div>
[2] => a><p class="wp-caption-text">Pendant Heart Photos</p></div>
)
[1] => Array
(
[0] => Pendant Heart Images
[1] => Pendant Heart Photos
[2] => Pendant Heart Photos
)
)
Code which I am using to save array value
$a = $g_img[1][0];
$b = $g_img[1][1];
$c = $g_img[1][2];
$a1 = $title[1][0];
$b1 = $title[1][1];
$c1 = $title[1][2];
Mysql query to save data
mysqli_query($con,"INSERT INTO data (Link, Title) VALUES ('$a','$a1')");
mysqli_query($con,"INSERT INTO data (Link, Title) VALUES ('$b','$b1')");
mysqli_query($con,"INSERT INTO data (Link, Title) VALUES ('$c','$c1')");
So If array data increases I have to assign each array value to different variable which is huge process I know there would be a shortcut
Plz Help
The query will not work because to start with, the number of field name are not equal to the number of values.
You could have passed your query in the following way:
for ($counter = 0; $counter <=2; $counter++){
$query = "INSERT INTO data (Link, Title) VALUES ('{$g_img[1][$counter]}', '{$title[1][$counter]}')";
$result = mysqli_query($con, $query);
}
Here I have assumed that $g_img and $title correspond to the array of links and titles respectively and the data connection is $con.

How to group the table rows and add summary row above the group?

I have an sql query that outputs a lot of information. What I need to do is group and summarize the information in the output table. Here is an example of what i'm trying to do:
name val1 val2 val3 total Run
some name 18 4 1 23
some name 5 4 1 23 2
some name 13 8 2 23 1
other name 2 2 0 4 1
and name 2 42 1 45 1
The name that is coming in from the database can appear more then once. If it does I group those items together and add the Summary row above which would have the same name but also compute the totals:
Val1 has to be added together
Val2, Val3 has to be the same as the row with the largest value in RUN cell
total value always stays the same.
There would be multiple occurrences of such grouping in the output table.
I tried to google my question but the closest that I got to what I was looking for was this this: How to add rows in middle of a table with jQuery?
which is not really what I am doing.
I'm not sure if there is an sql command that I could use to do that, or if it can be done in php or with use of jquery. Any suggestions will be appreciated.
Thank you!
Update:
I have tried using GROUP BY in sql, but it gives me syntax error:
SELECT name, val1, val2, val2, run
FROM tableName
WHERE ... ORDER BY name DESC GROUP BY name
(don't mind the WHERE ... I actually have statements there).
The only time it actually grouped the query when I have two or three results in the query and all of the three have the same name. So I though the GROUP BY is not the option.
In the php I am storing the name into a variable and checking if the name the same or not. if it's not the same i add master class to the row, if not the class is child, which helps me group it. However I didn't figure out a way to add a summary row above.
I was thinking for every time the name changes add a blank row and use jquery to populate it after page is loaded, however, for one time occurances of a name I do not need the summary.
As for, Val3 in the summary row I have made changes above. Val3 will be the same as the val3 in the row with the largest run value. I think I was confused by my own example.
I hope this information is more helpful.
Whenever I have to do something like this, I use multi-dimensional associative array with the top level keys being the highest level of grouping that I want to do. In your case, that would be "name".
In each element of that array, there is another assoc array with a key for each value that I want to keep track of. There is also a numbered sub-array that will contain each individual row that belongs in that grouping.
After I finish going through all the rows, I go through the resulting associative array and print the results.
For example:
<?php
/** Simulate of the results of your SQL query **/
$sql_result = array(
array("name"=>"some name ", "val1"=>5, "val2"=>4, "val3"=>1, "run" =>2),
array("name"=>"some name ", "val1"=>13, "val2"=>8, "val3"=>2, "run" =>1),
array("name"=>"other name", "val1"=>2, "val2"=>2, "val3"=>0, "run" =>1),
array("name"=>"and name", "val1"=>2, "val2"=>42, "val3"=>1, "run" =>1)
);
/** Add each result to your assoc array **/
$names = array();
foreach($sql_result as $row) {
$name = $row["name"];
// Create a new assoc array for each different name
if( !$names[$name] ) {
$names[ $name ] = array(
"name" => $row["name"],
"max_run" => $row["run"],
"val1" => $row["val1"],
"val2" => $row["val2"],
"val3" => $row["val3"],
"runs" => array( $row )
);
continue;
}
// Update the necessary values for the highest "run" number
if ($row["run"] > $names[ $name ]["max_run"]) {
$names[ $name ]["max_run"] = $row["run"];
$names[ $name ]["val2"] = $row["val2"];
$names[ $name ]["val3"] = $row["val3"];
}
// Update the reset of the values
$names[ $name ]["val1"] += $row["val1"];
$names[ $name ]["total"] = $names[ $name ]["val1"] + $names[ $name ]["val2"] + $names[ $name ]["val3"];
$names[ $name ]["runs"][] = $row;
}
/** Print your results **/
foreach ($names as $name) {
// Print your totals here like $name["total"], $name["val1"]
echo $name["name"]." ";
echo $name["val1"]." ";
echo $name["val2"]." ";
echo $name["val3"]." ";
echo $name["total"]."<br>";
if ( count($name["runs"]) > 1 ) {
foreach( $name["runs"] as $run ) {
echo print_r($run)."<br>";
}
}
echo "<hr>";
}
?>
This code is tested

Categories