Merging PHP arrays - php

I am working on a project at the moment, that allows the user to create any number of news headlines, articles and images, the only rule with this system is that a headline must have an article and an image. My question is on my form when I submit I get 2 arrays one is the $_POST and the other is $_FILES.
$_POST
Array
(
[campaign_title] => Another multiple test
[campaign_keyword] => Another multiple test
[introduction] => Another multiple test
[campaign_headline] => Array
(
[0] => Another multiple test headline 1
[1] => Another multiple test headline 2
)
[article] => Array
(
[0] => Another multiple test article 1
[1] => Another multiple test article 2
)
[save_multiple] => Save
)
$_FILES
Array
(
[article_image] => Array
(
[name] => Array
(
[0] => Intro-artists.gif
[1] => textbg1.png
)
[type] => Array
(
[0] => image/gif
[1] => image/png
)
[tmp_name] => Array
(
[0] => /private/var/tmp/phpwDAkGJ
[1] => /private/var/tmp/phpmvrMDg
)
[error] => Array
(
[0] => 0
[1] => 0
)
[size] => Array
(
[0] => 2841
[1] => 56506
)
)
)
Basically the method after submitting the form is the data is saved to a database, the 3 items of the post are saved in one table, the headlines and articles are saved in another table (sent with the id of the row just inserted) and then finally the images are saved, again sent with id of the first saved row.
I am having trouble understanding how I make sure the right images gets saved with the right ID, the DB saves are done by looping through the headlines and articles, but as the images are in a different array I cannot do this and make sure they are getting saved with right foreign id, can I merge the files into the post? Currently the solution I have for the headlines and articles is this,
foreach ($data['campaign_headline'] as $key => $headline) {
addMailerMultipleRelatedContent($mailerId, $headline, $data['article'][$key]);
}
function addMailerMultipleRelatedContent($mailerId, $headline, $article) {
extract($data);
//die(print_r($id));
$id = addRelatedMultipleContent($data['introduction'], $headline, $article,
$mailerId, mktime(), mktime());
}
function addRelatedMultipleContent($introduction, $headline, $content,
$mailer_id, $created_at, $updated_at){
$query = "INSERT INTO `mailer_content` (`id`, `introduction`, `headline`,
`content`, `mailer_id`,`created_at`, `updated_at`) VALUES ";
$query .= "(NULL, '" . makeSafe($introduction) . "', '" .
makeSafe($headline) . "', '" . makeSafe($content) . "', '" .
makeSafe($mailer_id) . "', " . makeSafe($created_at) . ", " .
makeSafe($updated_at) . ");";
$result = runInsert($query, __FUNCTION__);
//die(print_r($result));
return $result;
}
Is there away for me to work with images at the same time?
EDIT:
The HTML form,
<form method="post" action="/admin/editmultiple" enctype="multipart/form-data">
<fieldset class="toplined">
<label>Campaign Title</label>
<input type="text" name="campaign_title" value="<?echo (isset($mailers['mailer_title'])) ? $mailers['mailer_title'] : $_POST['campaign_title'];?>" class="extrawideinput" />
</fieldset>
<fieldset class="toplined">
<label>Campaign Type:</label>
<label>Multiple</label>
</fieldset>
<fieldset class="toplined">
<label>Campaign Keyword:</label>
<div class="forminputblock">
<input type="text" name="campaign_keyword" value="<?echo (isset($mailers['mailer_header'])) ? $mailers['mailer_header'] : $_POST['campaign_keyword'];?>" class="extrawideinput" />
</div>
</fieldset>
<fieldset class="toplined">
<label>Introduction</label>
<div class="forminputblock">
<input type="text" name="introduction" value="<?echo (isset($mailers['introduction'])) ? $mailers['introduction'] : $_POST['introduction'];?>" class="extrawideinput" />
</div>
</fieldset>
<fieldset class="toplined">
<label>Headline</label>
<div class="forminputblock">
<input type="text" name="campaign_headline[]" value="<?echo (isset($mailers['headline'])) ? $mailers['headline'] : $_POST['campaign_headline'];?>" class="extrawideinput" />
</div>
</fieldset>
<fieldset class="toplined">
<label>Image:</label>
<input type="file" name="article_image[]">
</fieldset>
<fieldset class="toplined">
<label>Story:</label>
<div class="forminputblock">
<textarea name="article[]" class="js_editable_textarea deeptext" rows="1" cols="1"><?echo (isset($mailers['content'])) ? $mailers['content'] : $_POST['article'];?></textarea>
</fieldset>
<div id="result">
</div>
<fieldset class="toplined">
+ Add Another New Article
</fieldset>
<fieldset class="toplined">
<input type="submit" name="save_multiple" value="Save" />
</fieldset>
</form>

With the same key you use to access the articles sub array, you can access the different fields in the $_FILES array. Obviously you can merge the two arrays, but it isn't necessary for you to work with them.
Also, you should note that you have to copy the actual data from the temporary location to where ever you would like to permanently store it. Make sure to use the [is_uploaded_file()][1] and [move_uploaded_file()][2] methods to prevent potential attacks via file uploads.
[1]: http://www.php.net/manual/en/function.is-uploaded-file.php is_uploaded_file()
[2]: http://www.php.net/manual/en/function.move-uploaded-file.php move_uploaded_file()

I'm not sure that you would want to merge the two arrays, as you need to perform different actions on each array.
With the $_FILES array, the uploaded images will be stored in a temporary location, the images need to be moved to a more permanent location before being referenced in your database.

EDIT: I've just recoded you an entire example of how it could easily work. (uses jquery as an example)
<?php
echo '<pre>';
print_r($_POST);
echo '</pre>';
?>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript">
$(function() {
var position = 1;
$(".add").click(function(){
var parent = $(this).parent();
var newField = $(this).parent().clone(true).insertAfter(parent);
/* title */
var newName = 'articles['+ position + '][title]';
newField.children(".name").attr("name", newName);
/* content */
newName = 'articles['+ position + '][content]';
newField.children(".content").attr("name", newName);
/* content */
newName = 'articles['+ position + '][checkbox]';
newField.children(".checkbox").attr("name", newName);
newField.slideDown();
position++;
});
});
</script>
<h1>example</h1>
<form action="" method="post">
<fieldset class="article">
<label style="display:block">Article title</label>
<input type="text" name="articles[0][title]" value="" class="name" />
<label style="display:block">Article content</label>
<textarea name="articles[0][content]" cols="40" rows="10" class="content"></textarea>
<label style="display:block">Checkbox</label>
<input type="checkbox" name="articles[0][checkbox]" value="1" class="checkbox" />
<br />
add new after
</fieldset>
<br />
<input type="submit" value="submit" name="submit" />
</form>

Related

Building a php multidimensional array from form elements

I'm trying to get a multidimensional array to store the info from three separate elements (caption, image, and subfolder). The three elements are descriptions from photos that individuals may upload onto my site. I've built an initial page that asks the visitor how many photos they intend to upload and from which country(an input type=select). Based upon their response on that initial form, the second page uses a loop to generate the appropriate number of , , and elements. Once the second form is submitted the intention is to upload the info to the server which it does. The second objective is to store that information inside the multidimensional array such as below in order to upload into a MySQL table. My dilemma is in getting the image names presumably from ($_FILES['image']['name']) to insert themselves into my multidimensional array. The captions '' insert themselves into the multidimensional array as does the country name ('name=subfolder']) but not the image names. I'd greatly appreciate anyone willing to help with this.
Thank you.
Array ( [caption] => Array ( [0] => Nice Simple Picture [1] Another Nice Simple Picture=> )
[image] => [subfolder] => Array ( [0] => Italy ) [upload] => UPLOAD )
Here's a bit of how I've attempted to go about this..
<?php
$file=$_FILES['image']['name'];
$expected = array('image','subfolder','caption');
foreach ($_POST as $key => $value) {
if (in_array ($key, $expected)) {
${$key} = mysql_real_escape_string($value); }}
$sql = "INSERT INTO images (file_name, country, caption)
VALUES ('$image', '$subfolder', '$caption')";
$result = mysql_query($sql) or die (my_sql_error()); }
?>
<form action="<?php $_SERVER['PHP_SELF']; ?>" id="form1" name="form1" method="POST"
enctype="multipart/form-data">
<?php
for ($i=0; $i<$imgnumb; $i++) {
echo "<input type=\"file\" name=\"image[".$i."]\" /> <input type=\"text\"
name=\"caption[".$i."]\" /><br />"; }
?>
<br />
<input value="<?php echo $file; ?>" name="image" type="hidden" />
<input value="<?php echo $location; ?>" name="subfolder" type="hidden" />
<input value="<?php echo $_POST['caption']; ?>" name="caption" type="hidden" />
<input type="submit" name="upload" id="next" value="UPLOAD" />
</form>

How to insert value of dynamically created input boxes into database [duplicate]

This question already exists:
how to post value of 3 input fields into database
Closed 9 years ago.
hello developers i am creating 2 text boxes and 1 select box dynamically using java script function... now i want to post the value of (n) fields created into database (relevant table)
as i am using codeigniter so m posting the script and code
this is the simple java script that i am using
<script>
var counter=1;
function generateRow() {
var count="<font color='red'>"+counter+"</font>";
var temp ="<p> <div class='_25'><input type='textbox' id='textbox' name='stop"+counter+"' placeholder='Stop Name'></input></div> <div class='_25'><input type='textbox' id='textbox' name='timing"+counter+"' placeholder='Timing'></input></div> <div class='_25'><select id='ampm"+counter+"' name='ampm"+counter+"'><option>a.m</option><option>p.m</option></select> </div>";
var newdiv = document.createElement('div');
newdiv.innerHTML = temp + count;
var yourDiv = document.getElementById('div');
yourDiv.appendChild(newdiv);
counter++;
}
</script>
and this is my division on php file
<div id="div">
</div>
<p> </p>
<div class="_25">
<p>
<input type="button" name="button" class="button red" id="button" value="Add" onclick="generateRow() "/></a>
</p>
</div>
<input type='button' value='Remove Button' id='removeButton'>
and this is my related table fields
route_number stop_name am_pm timing
My favorite way to do this is to use the DOM as much as possible. Don't use counters unless you absolutely have to (they're just a source of bugs). Here's a quick example:
Html/JS/jQuery (can vary, I crafted this to make it easy to follow):
<form method="POST" id="theForm">
<div id="fields">
<input type="text" name="fields[]"/>
</div>
<input type="button" id="addField" value="Add Field"/>
</form>
<script type="text/javascript">
$(document).ready(function() {
$('#addField').click(function() {
$('#fields').append(
$('<input type="text" name="fields[]"/>')
);
})
});
</script>
Note how I don't need to use any sort of counting variable. Just like PHP, you can create an array of POST variables without specifying indexes by using [] and the server (or browser? I'm not sure) will build the array for you. The order in which the <input /> fields are rendered on the page will be the order they are provided to your PHP via $_POST. This code...
foreach ($_POST['fields'] as $fieldIndex => $fieldValue) {
doStuff($fieldValue);
}
... will process each field in the order they were added. You can even use JavaScript to re-order or remove the inputs and that will be reflected in $_POST. This method, coupled with JSON encoding, makes for a fast and easy way to handle multi-input, free-form fields.
Update:
Applying the above code to your use-case requires a small addition that may not be obvious. You'll need to create an array for each of the three inputs (stop, timing, and ampm) like so:
<form method="POST" id="theForm">
<div id="fields">
<input type="text" name="fields[stop][]"/>
<input type="text" name="fields[timing][]"/>
<select name="fields[ampm][]">
<option value="am">AM</option>
<option value="pm">PM</option>
</select>
<br/>
</div>
<input type="button" id="addField" value="Add Field"/>
</form>
<script type="text/javascript">
$(document).ready(function() {
$('#addField').click(function() {
$('#fields').append(
$('<input type="text" name="fields[stop][]"/>'),
$('<input type="text" name="fields[timing][]"/>'),
$('<select name="fields[ampm][]"><option value="am">AM</option><option value="pm">PM</option></select>'),
$('<br/>')
);
})
});
</script>
Filling out this form with some test data yields the following array:
[fields] => Array
(
[stop] => Array
(
[0] => aaa
[1] => bbb
)
[timing] => Array
(
[0] => 1111
[1] => 2222
)
[ampm] => Array
(
[0] => am
[1] => pm
)
)
And to process that in PHP requires a simple old-school loop:
$numFields = count($_POST['fields']['stop']);
for ($i = 0; $i < $numFields; $i++) {
// Pack the field up in an array for ease-of-use.
$field = array(
'stop' => $_POST['fields']['stop'][$i],
'timing' => $_POST['fields']['timing'][$i],
'ampm' => $_POST['fields']['ampm'][$i]
);
saveToDatabase($field);
}
Unfortunately I don't have time right now to make sure all that is correct. It should be, and if its not it may still help :). I'll check back in a few hours.
name your dynamic input box "stop["+counter+"]" (using braces as part of the name) instead of adding a counter to the end of the name. Then in your post data, $_POST['stop'] will be an array of values that you can just foreach loop over with the counter as the key in the sub-array. And $_POST['stop'][1] will correspond to $_POST['timing'][1]...etc.
You can construct the following HTML input fields:
<input type="text" name="data[]" />
<input type="text" name="data[]" />
<input type="text" name="data[]" />
// ...
Which will lead to an array keyed data inside $_REQUEST super global, when you var_dump($_REQUEST['data']). Try it out. You don't even need to index the data[] array, since PHP will do it for you.
You might want to process your $_REQUEST['data'] or $_POST['data'] array with a foreach loop construct:
foreach($_REQUEST['data'] as $data){
// $data is the corresponding input field's value
}

Using multi-dimensional arrays in an HTML form

Issue 1: I have a form that contains a list of events pulled from a database, alongside which are checkboxes for customers to register their attendance. There is an additional checkbox to indicate any special requirements, as well as a text field to elaborate ('If yes, please provide additional details...').
I would like to store every event a customer is attending in a multi-dimensional array containing the event ID, 'yes/no' for special requirements and details of any such requirements. I thought I was on track with:
<form id="bookingform" method="post" action="booking-details.php">
<fieldset>
<legend>Personal information</legend>
<div class="bookingitem">
<label for="firstname">First name</label> <input type="text" name="firstname" id=
"firstname" />*<br />
</div>
<div class="bookingitem">
<label for="surname">Surname</label> <input type="text" name="surname" id=
"surname" />*<br />
</div>
<div class="bookingitem">
<label for="company">Company</label> <input type="text" name="company" id=
"company" />*<br />
</div>
</fieldset>
<fieldset>
<legend>Which exhibition(s)?</legend>
<div class="bookingitem">
<?php
$venues_query="SELECT exhibitions.exhib_id AS exhib_id, venues.venue_name AS venue, DATE_FORMAT(exhibitions.exhib_date, '%d/%m/%y') AS date FROM venues, exhibitions WHERE exhibitions.venue_id = venues.venue_id AND (exhibitions.exhib_date>=CURDATE())ORDER BY exhibitions.exhib_date";
$venues_result=mysql_query($venues_query);
while($venues=mysql_fetch_array($venues_result, MYSQL_ASSOC)){
echo '<input type="checkbox" name="registrations['.$venues['exhib_id'].'][id]" /> '.$venues['venue'].' - '.$venues['date'].'<br/>';
echo '<input type="checkbox" name="registrations['.$venues['exhib_id'].'][requirements]" />Special requirements?<br/>';
echo 'If yes, please give more details... <input type="text" name="registrations['.$venues['exhib_id'].'][requirements_details]" />';
}
mysql_close();
?>
</div>
</fieldset>
<fieldset>
<legend>Terms and conditions:</legend>
<p>T&Cs here</p>
<div>
<input type="submit" class="buttons" name="submit" value="Submit" />
</div>
</fieldset>
</form>
... but when I do var_dump($_POST['registrations']);, I'm only getting:
array(4) { [0]=> string(5) "00132" [1]=> string(5) "00140" [2]=> string(5) "00135" [3]=> string(5) "00136" }
The five-digit numbers are the event IDs, pulled from the database (I've registered for four events in this example), but the other info seemingly isn't being stored. I expect it's blindingly obvious, but can anyone spot where I'm going wrong?
I want to be able to loop through through the values (as per this example here) using the following code:
foreach ( $_POST['registrations'] as $registration )
{
echo '$registration[id]';
echo '$registration[requirements]';
echo '$registration[requirements_details]';
// etc
}
Issue 2: I would like to make sure that when the special requirements box is ticked, the details box is also filled out. Previously, I had three separate arrays for each part of the form, and did a count() on the number of ticks and the number of input boxes completed. If they didn't match, the form wouldn't process. However, I'm sure there's a much easier way of achieving this and would be grateful for any advice!
When I try what I believe is your resultant HTML, I get the following from print_r:
Array
(
[registrations] => Array
(
[11111] => Array
(
[id] => on
[requirements] => on
[requirements_details] => 1
)
[22222] => Array
(
[id] => on
[requirements] => on
[requirements_details] => 2
)
[33333] => Array
(
[id] => on
[requirements] => on
[requirements_details] => 3
)
[44444] => Array
(
[id] => on
[requirements] => on
[requirements_details] => 4
)
[55555] => Array
(
[id] => on
[requirements] => on
[requirements_details] => 5
)
)
)
Can you update your question with the HTML produced for the complete form?

Form file field value not posting to $_POST

I'm doing some tests with forms and ran into a snag, I have a very simple test script that works, but the problem is that my FILE field in the form is not getting submitted to the $_POST array for some reason, if I take out encode="multipart/form-data" it does, otherwise I just get the other fields. Here is the script:
<?PHP
print_r($_POST);
echo"<br>";
print_r($_FILES);
$name = $_FILES["img1"]["name"];
$tmp_name = $_FILES["img1"]["tmp_name"];
$uploads_dir = "uploads";
echo "<br>TEMP NAME:</b>";
echo $tmp_name;
move_uploaded_file($tmp_name, "$uploads_dir/$name");
?>
<html>
<body>
<br><br>
-------------------------
<form name="test" id="test" action="index.php" method="post" enctype="multipart/form-data">
<label>Name</label>
<input type="text" name="title" id="title">
<br>
<label>File</label>
<input type="file" name="img1" id="img1" size="40">
<br>
<input type="submit" value="submit">
</form>
The output is:
POST ARRAY: Array ( [title] => some title )
FIELS ARRAY: Array ( [img1] => Array ( [name] => chicken.jpg [type] => image/jpeg [tmp_name] => /tmp/phpcrBLw9 [error] => 0 [size] => 30940 ) )
TEMP NAME:/tmp/phpcrBLw9
As you can see, the POST only has the title, not the file name, I need it to have both for programming reasons, is there a way to do that without having to cheat / have hidden fields or edited values manually?
You will not be able to see $_FILES inside $_POST. They are different superglobals, if you vardump($_FILES); you will see that it stores all the information about the uploaded file, like size, tmp name etc. This is how PHP has been built, and the only thing you can do about it is access the name using
$_FILES['img1']['name']
You can access the name of the uploaded file here:
$_FILES["img1"]["name"]

PHP: Manipulating Multdimensional Array in Form Data?

I have a form that includes the first name and last name of a person. The user can add multiple people using a link, that creates new input fields via JS. Here's an example of a form that includes 2 people:
<form action="" method="post">
<input type="text" class="required" name="people[first][]" />
<input type="text" class="required" name="people[last][]" />
<input type="text" class="required" name="people[first][]" />
<input type="text" class="required" name="people[last][]" />
<input type="submit" name="submit">
</form>
I'm trying to figure out a way to insert this data into the database. I've tried using:
foreach ($_POST['people'] as $person) {
foreach ($person as $value) {
echo $value . '<br/>';
}
}
.. which results in
first name 1
first name 2
last name 1
last name 2
I'm trying to group the results somehow so I can insert a new row for each first name x + last name x combination.
Create the input elements like this:
<input type="text" name="people[0][first]" />
<input type="text" name="people[0][last]" />
<input type="text" name="people[1][first]" />
<input type="text" name="people[1][last]" />
In your PHP:
foreach ($_POST['people'] as $person) {
echo $person['first'].' '.$person['last'].'<br />';
}
$_POST['people']['first'] is an array of first names.
$_POST['people']['last'] is an array of last names.
You can merge them into an array of arrays like this:
$people = $_POST['people'];
$length = count($people['first']);
for($i = 0; $i < $length; $i++)
$temp[] = array('first' => $people['first'][$i], 'last' => $people['last'][$i]);
$people = $temp;
The resulting array in $people will be an array of associative arrays, and might look like:
Array
(
[0] => Array
(
[first] => Jim
[last] => Smith
)
[1] => Array
(
[first] => Jenny
[last] => Johnson
)
)
which is equivalent to the array you would get by modifying your HTML as bsdnoobz has shown you can do as well. Iterating through it would be the same too:
foreach ($people as $person) {
echo $person['first'] . ' ' . $person['last'] . '<br />';
}

Categories