Form multiple inputs to PHP Multidimensional Array - php

I'm a new with PHP Array and have a form that input multiple parent-child data and save into an array. HTML will be something like this:
<ul>
<li><input type="text" name="group[0][name]" placeholder="Group name">
<ul>
<li>
<p>Member #1</p>
<input type="text" name="group[0][member][0][name]" placeholder="Name">
<input type="text" name="group[0][member][0][age]" placeholder="Age">
</li>
<li>
<p>Member #2</p>
<input type="text" name="group[0][member][1][name]" placeholder="Name">
<input type="text" name="group[0][member][1][age]" placeholder="Age">
</li>
</ul>
</li>
<li><input type="text" name="group[1][name]" placeholder="Group name">
<ul>
<li>
<p>Member #1</p>
<input type="text" name="group[1][member][0][name]" placeholder="Name">
<input type="text" name="group[1][member][0][age]" placeholder="Age">
</li>
</ul>
</li>
</ul>
PHP code:
$output = array();
$i = 0;
foreach ( $_POST['group'] as $group ) {
$members = array();
$m = 0;
foreach ( $_POST['group'][$i]['member'] as $name ) {
$members[$i][] = array(
'name' => $name,
'age' => $_POST['group'][$i]['member'][$m]
);
$m++;
}
$output[] = array(
'group_name' => $_POST['group'][$i]['name'],
'members' => $members[$i]
);
$i++;
}
var_dump( $output );
And I got this result:
array (size=2)
0 =>
array (size=2)
'group_name' => string 'Group 1' (length=7)
'members' =>
array (size=2)
0 =>
array (size=2)
...
1 =>
array (size=2)
...
1 =>
array (size=2)
'group_name' => string 'Group 2' (length=7)
'members' =>
array (size=1)
0 =>
array (size=2)
...
Can't get the member names and ages to be submitted into array. Can somebody help me? And sorry if I didn't explain this correctly. Thanks!

You have to process down the heirarchy, using the new arrays created by the foreach loop is also easier to understand than going back to the master array like you woudl have to in a for loop
$output = [];
foreach ( $_POST['group'] as $group ) {
$mem = []; // init the members each time you start a new group
foreach ( $group['member'] as $member) {
$mem[] = ['name' => $member['name'], 'age' => $member['age']];
}
$output[] = [ 'group_name' => $group, 'members' => $mem ];
}

Related

Codeigniter - Multiple Input using foreach loop [duplicate]

I am Inserting a multiple form input data in to database using Codeigniter.
I have this post input array:
Array
(
[subject_id] => Array
(
[0] => 1
[1] => 1
)
[question] => Array
(
[0] => test
[1] => test2
)
[option1] => Array
(
[0] => test
[1] => test2
) )
I don't get that how do i convert this array to insert How to insert this array using Insert batch.
$this->db->insert_batch('mytable', $data);
This is the form code which i use for posting the data:
<form method="post">
<input type="text" name="subject_id[]" >
<input type="text" name="question[]" >
<input type="text" name="record[]" >
// Down side Part is appended when user want to add more question
<input type="text" name="subject_id[]" >
<input type="text" name="question[]" >
<input type="text" name="record[]" >
<input type="submit" name="submit" >
</form>
Below is the Array format which i want.
$data = array(
array(
'subject_id' => 'My title' ,
'question' => 'My Name' ,
'option1' => 'My date'
),
array(
'subject_id' => 'Another title' ,
'question' => 'Another Name' ,
'option1' => 'Another date'
)
);
<?php
$i = 0;
foreach($subject_id as $key=>$val)
{
$data[$i]['subject_id'] = $val;
$data[$i]['question'] = $question[$key];
$data[$i]['option1'] = $record[$key];
$i++;
}
$this->db->insert_batch('mytable', $data);
?>
Try like below:Assume $records is an array that you want to insert.
foreach ($records as $record)
{
for ($i=0; $i < count($record); $i++)
{
$data[$i]['subject_id'] = $record['subject_id'][$i];
$data[$i]['question'] = $record['question'][$i]
$data[$i]['option1'] = $record['option1'][$i];
}
}
Then
$this->db->insert_batch('mytable', $data);

How to submit and insert Multiple rows into mysql in a single form [duplicate]

I am Inserting a multiple form input data in to database using Codeigniter.
I have this post input array:
Array
(
[subject_id] => Array
(
[0] => 1
[1] => 1
)
[question] => Array
(
[0] => test
[1] => test2
)
[option1] => Array
(
[0] => test
[1] => test2
) )
I don't get that how do i convert this array to insert How to insert this array using Insert batch.
$this->db->insert_batch('mytable', $data);
This is the form code which i use for posting the data:
<form method="post">
<input type="text" name="subject_id[]" >
<input type="text" name="question[]" >
<input type="text" name="record[]" >
// Down side Part is appended when user want to add more question
<input type="text" name="subject_id[]" >
<input type="text" name="question[]" >
<input type="text" name="record[]" >
<input type="submit" name="submit" >
</form>
Below is the Array format which i want.
$data = array(
array(
'subject_id' => 'My title' ,
'question' => 'My Name' ,
'option1' => 'My date'
),
array(
'subject_id' => 'Another title' ,
'question' => 'Another Name' ,
'option1' => 'Another date'
)
);
<?php
$i = 0;
foreach($subject_id as $key=>$val)
{
$data[$i]['subject_id'] = $val;
$data[$i]['question'] = $question[$key];
$data[$i]['option1'] = $record[$key];
$i++;
}
$this->db->insert_batch('mytable', $data);
?>
Try like below:Assume $records is an array that you want to insert.
foreach ($records as $record)
{
for ($i=0; $i < count($record); $i++)
{
$data[$i]['subject_id'] = $record['subject_id'][$i];
$data[$i]['question'] = $record['question'][$i]
$data[$i]['option1'] = $record['option1'][$i];
}
}
Then
$this->db->insert_batch('mytable', $data);

htmlspecialchars on an array of arrays is not working

I have this form with a bunch of sections, and some of them have name of an array because they are supposed to add up dynamically. I'm trying to perform htmlspecialchars on them first and then once the submit button is clicked, echo them out on a next confirmation page, but it won't work for some reason. I did print_r on $clean, but it didn't show the input $value of them, so I don't know where I did something wrong.
It would be great if somebody could help me on this.
Thank you.
Here is a part of the htmlspecialchars code.
$clean = array();
if( !empty($_POST) ) {
foreach( $_POST as $key => $value ) {
if( is_array($key)){
foreach($key as $key2 => $value2)
$clean[$key2] = htmlspecialchars( $value2, ENT_QUOTES);
} else {
$clean[$key] = htmlspecialchars( $value, ENT_QUOTES);
}
}
}
This is a html part of it
<div class="seconf-h-form">
<label>Multiple</label>
<input type="radio" id="r2" name="team_select"
onchange="toggleFunc('ex_t_button');" value="Multiple"/>
</div>
<div class="element_wrap" id="box_2">
<input type="submit" name="add" id="add" value="add more">
<label>The name of your team</label>
<input type="text" name="ex_team_n[]" id="ex_team_n"/>
<select name="ex_amount[]">
<option value="">Select</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
</select>
<div id="add_section"></div>
and this is the part where I echo them out
<div class="element_wrap">
<label>The name of your team</label>
<p><?php echo $clean['ex_team_n']; ?></p>
</div>
<div class="element_wrap">
<label>The number of your team</label>
<p><?php echo $clean['ex_amount']; ?></p>
</div>
<input type="hidden" name="amount" value="<?php if(
$clean['team_select'] === "Multiple"){echo $clean['ex_team_n'];} ?>">
<input type="hidden" name="amount" value="<?php if(
$clean['team_select'] === "Multiple"){echo $clean['ex_amount'];} ?>">
You can use array_walk_recursive() to escape all data inside an array:
// Sample data, you can use $_POST instead or any other array
$array = array(
[
'a_key' => '<b>html</b>',
'b_key' => 'another code',
'c_key' => array('<script>alert(\'Hello\');</script>', 'No code, no change'),
],
[
'd_key' => '<small>ssup</small>',
'e_key' => 'stack',
'f_key' => 'overflow',
],
);
// Function to escape the value, you must pass the item by reference using the & operator
function html_escape(&$item){
$item = htmlspecialchars($item, ENT_QUOTES);
}
// Dump data before escaping
var_dump($array);
// Walk recursively through the array and call our function
array_walk_recursive($array, 'html_escape');
// Dump data after escaping
var_dump($array);
The data dumped before escaping
array (size=2)
0 =>
array (size=3)
'a_key' => string '<b>html</b>' (length=11)
'b_key' => string 'another code' (length=46)
'c_key' =>
array (size=2)
0 => string '<script>alert('Hello');</script>' (length=32)
1 => string 'No code, no change' (length=18)
1 =>
array (size=3)
'd_key' => string '<small>ssup</small>' (length=19)
'e_key' => string 'stack' (length=5)
'f_key' => string 'overflow' (length=8)
The data dumped after escaping
array (size=2)
0 =>
array (size=3)
'a_key' => string '<b>html</b>' (length=23)
'b_key' => string '<a href="http://example.com/">another code</a>' (length=68)
'c_key' =>
array (size=2)
0 => string '<script>alert('Hello');</script>' (length=54)
1 => string 'No code, no change' (length=18)
1 =>
array (size=3)
'd_key' => string '<small>ssup</small>' (length=31)
'e_key' => string 'stack' (length=5)
'f_key' => string 'overflow' (length=8)
Documentation for array_walk_recursive()
You're not iterating over the right object and not creating the inner array.
Replace the lines:
if( is_array($key)){
foreach($key as $key2 => $value2)
$clean[$key2] = htmlspecialchars( $value2, ENT_QUOTES);
with
if( is_array($value)){
foreach($value as $key2 => $value2) {
if (!isset($clean[$key])) $clean[$key] = array();
$clean[$key][$key2] = htmlspecialchars( $value2, ENT_QUOTES);
}
And then it should work properly.
function sanitizeMyArray($array) {
array_walk_recursive($array, 'standard');
return $array;
}
function standard(&$item, $key) {
//You must return this to $item for it to work.
$item = htmlspecialchars($item, ENT_QUOTES);
return $item;
}
$results = sanitizeMyArray($array);
print_r($results)

Codeigniter Insert Batch array

I am Inserting a multiple form input data in to database using Codeigniter.
I have this post input array:
Array
(
[subject_id] => Array
(
[0] => 1
[1] => 1
)
[question] => Array
(
[0] => test
[1] => test2
)
[option1] => Array
(
[0] => test
[1] => test2
) )
I don't get that how do i convert this array to insert How to insert this array using Insert batch.
$this->db->insert_batch('mytable', $data);
This is the form code which i use for posting the data:
<form method="post">
<input type="text" name="subject_id[]" >
<input type="text" name="question[]" >
<input type="text" name="record[]" >
// Down side Part is appended when user want to add more question
<input type="text" name="subject_id[]" >
<input type="text" name="question[]" >
<input type="text" name="record[]" >
<input type="submit" name="submit" >
</form>
Below is the Array format which i want.
$data = array(
array(
'subject_id' => 'My title' ,
'question' => 'My Name' ,
'option1' => 'My date'
),
array(
'subject_id' => 'Another title' ,
'question' => 'Another Name' ,
'option1' => 'Another date'
)
);
<?php
$i = 0;
foreach($subject_id as $key=>$val)
{
$data[$i]['subject_id'] = $val;
$data[$i]['question'] = $question[$key];
$data[$i]['option1'] = $record[$key];
$i++;
}
$this->db->insert_batch('mytable', $data);
?>
Try like below:Assume $records is an array that you want to insert.
foreach ($records as $record)
{
for ($i=0; $i < count($record); $i++)
{
$data[$i]['subject_id'] = $record['subject_id'][$i];
$data[$i]['question'] = $record['question'][$i]
$data[$i]['option1'] = $record['option1'][$i];
}
}
Then
$this->db->insert_batch('mytable', $data);

PHP is the next key a part of the current?

Hey guys I'm trying to see where my pairs of keys stop, I have arrays built like this
EDIT People are getting really confused so I'm using a real array instead of an example
array (
'key' => '',
'po' => '',
'label' => '',
'report_key' => '',
'shipper' => '',
'status' => '',
'location' => '',
'inspector' => '',
'commodity' => '',
'brand' => '',
'case_count' => '',
'variety' => '',
'style' => '',
'grower_lot' => '',
'pack_date' => '',
// grouping 4 items
'berry_size1' => '',
'berry_size2' => '',
'berry_size3' => '',
'berry_size4' => '',
// grouping 3 items
'bunch_color1' => '',
'bunch_color2' => '',
'bunch_color3' => '',
// grouping 2 items
'color1' => '',
'color2' => '',
// grouping 3 items
'stem1' => '',
'stem2' => '',
'stem3' => '',
// grouping 2 items
'shatter1' => '',
'shatter2' => '',
// grouping 2 items
'splits1' => '',
'splits2' => '',
// grouping 2 items
'wet_sticky1' => '',
'wet_sticky2' => '',
'overall_quality' => '',
// grouping 2 items
'sugar_brix1' => '',
'sugar_brix2' => '',
'rating' => '',
'comments' => '',
)
I came up with some stupid way that really doesn't work to try and sort things out, its extremely backwards, honestly I'm pretty embarrassed by my attempt.
foreach($obj as $key=>$val) {
if(strpos( preg_replace('/[^a-z]/i', '', $key),
preg_replace('/[^a-z]/i', '', $all_keys[$key+$b+1])
) !== false) { echo "<p>$key</p>"; // items 1-3 will show
} elseif(strpos(preg_replace('/[^a-z]/i', '', $key),
preg_replace('/[^a-z]/i', '', $all_keys[$key+$b-1])
) !== false) { echo "<p>$key</p>"; // show last item
} else {
$in.='<aside class="left">';
$in .= "<label for='$key'>". ucwords(strtolower(str_replace('_',' ',$key))) ."</label><br/>";
$in .= ($key=='key') ? "<input type='text' value='". $objLastId ."' id='$key' class='disabled' disabled='disabled'>" : "<input type='text' value='' name='$key' id='$key'>";
$in.='</aside>';
$b++;
}
}
Anyway what I'm really trying to achieve is something like this, could someone steer me in the right direction please?
<style>
.row2 input {width: 50px !important;}
.row3 input {width: 27px !important;}
.row4 input {width: 15px !important;}
</style>
// stem was a 2 item group, so should have the row4 class
// and should have the second item appended by a
// all be inside the same grouping, like below ...
<aside class="left row2">
<label for="color1">Color</label>
<br/><input type="text" value="" name="color1" id="color1">
<input type="text" value="" name="color2" id="color2">
</aside>
// stem was a 3 item group, so should have the row4 class
// and should have items 2-3 appended by a all be inside
// the same grouping, like below ...
<aside class="left row3">
<label for="stem1">Stem</label>
<br><input type="text" id="stem1" name="stem1" value="">
<input type="text" id="stem2" name="stem2" value="">
<input type="text" id="stem3" name="stem3" value="">
</aside>
// berry_size was a 4 item group, so should have the row4 class
// and should have items 2-4 appended by a all be inside
// the same grouping, like below ...
<aside class="left row4">
<label for="berry_size1">Berry Size</label>
<br/><input type="text" id="berry_size1" name="berry_size1" value="">
<input type="text" id="berry_size2" name="berry_size2" value="">
<input type="text" id="berry_size3" name="berry_size3" value="">
<input type="text" id="berry_size4" name="berry_size4" value="">
</aside>
... or ...
// this is a single, so no extra class and ....
<aside class="left">
<label for="other_item">Other Item</label>
<br/><input type="text" id="other_item" name="other_item" value="">
</aside>
What I see this really boiling down to is reading the next array keys name (I stripped the name and used the integer in my version), atleast I think that's the right way to do it?
$arr = array(
'other_item' => 'value',
// this one ranges 1-3
'first_name1' => 'value',
'first_name2' => 'value',
'first_name3' => 'value',
// this one ranges 1-4
'next_name1' => 'value',
'next_name2' => 'value',
'next_name3' => 'value',
'next_name4' => 'value',
'other_item' => 'value',
// this one ranges 1-4
'last_name1' => 'value',
'last_name2' => 'value',
'last_name3' => 'value',
'last_name4' => 'value',
'other_item' => 'value'
);
$newarr = array();
foreach($arr as $key=>$value)
{
if (preg_match('#^([^\d]+)#', $key, $matches)===1)
$newarr[$matches[1]][] = $value;
}
print_r($newarr);
Output:
Array
(
[other_item] => Array
(
[0] => value
)
[first_name] => Array
(
[0] => value
[1] => value
[2] => value
)
[next_name] => Array
(
[0] => value
[1] => value
[2] => value
[3] => value
)
[last_name] => Array
(
[0] => value
[1] => value
[2] => value
[3] => value
)
)
And do whatever you want to do with it. Like that code (just an example, not a very nice one)
foreach($newarr as $name => $block)
{
$cnt = count($block);
echo '<aside class="left'.($cnt>1?' row' . $cnt:'').'">
<label for="' . $name . ($cnt>1?'1':''). '">' .
ucwords(str_replace('_', ' ', $name)) . '</label>
<br/>';
foreach($block as $key=>$element)
{
echo ($key>0?' ':'') . '<input type="text" value="" name="' . $name .
($cnt>1?($key+1):'') . '" id="' . $name .
($cnt>1?($key+1):'') . '">' . "\n";
}
echo '</aside>' . "\n";
}
It gives:
<aside class="left">
<label for="other_item">Other Item</label>
<br/><input type="text" value="" name="other_item" id="other_item">
</aside>
<aside class="left row3">
<label for="first_name1">First Name</label>
<br/><input type="text" value="" name="first_name1" id="first_name1">
<input type="text" value="" name="first_name2" id="first_name2">
<input type="text" value="" name="first_name3" id="first_name3">
</aside>
<aside class="left row4">
<label for="next_name1">Next Name</label>
<br/><input type="text" value="" name="next_name1" id="next_name1">
<input type="text" value="" name="next_name2" id="next_name2">
<input type="text" value="" name="next_name3" id="next_name3">
<input type="text" value="" name="next_name4" id="next_name4">
</aside>
<aside class="left row4">
<label for="last_name1">Last Name</label>
<br/><input type="text" value="" name="last_name1" id="last_name1">
<input type="text" value="" name="last_name2" id="last_name2">
<input type="text" value="" name="last_name3" id="last_name3">
<input type="text" value="" name="last_name4" id="last_name4">
</aside>
As far as I can tell you just want to modify your output based on your 'key type'. I am thinking something like this:
foreach($obj as $key => $val)
{
$parts = explode('_', $key);
switch($parts[0])
{
case 'first':
// Do something here
break;
case 'other':
// Do something here
break;
case 'next':
// Do something here
break;
case 'last':
// Do something here
break;
}
}
I think I might be missing something however, as you appear to be checking 'next' elements...

Categories