I have the ability to add custom fields in a project I am making. I have a page that has all the text inputs on it. Each custom field is named consecutively (field1, field2, field3) according to the order they were created. Since the user will have the ability to add as many as they want, how can I select each one so as to post their values to the database?
Hope this makes sense...
You should name the fields with array notation, as follows:
<input name='field[]' type='text' />
<input name='field[]' type='text' />
You can then retrieve the data from $_POST (or $_GET) as
$_POST['field'][0]
$_POST['field'][1]
try this:
for($i=1;$i<=3;$i++) {
print ${'field' . $i} . "<br>";
}
Here's how you would collect them if they are passed in _GET/_POST
$i = 1;
$custom_fields = array();
while (!empty($_REQUEST["field$i"]) {
$custom_fields[] = $_REQUEST["field$i"];
$i++;
}
Assuming that each of these fields will be posted, you can use a simple while loop and check that the variable is set:
$i = 1;
while ( isset($_POST['field' . $i]) ) {
// Do what you need to do to the variable here
// Whatever you do, do not forget this line
$i += 1;
}
Related
Here is my PHP variable:
$container = $_POST['containerNumber'];
Inside $_POST['containerNumber'], there are multiple container numbers that are retrieved when a user checks a checkbox from a form. That code is not necessary to display. Just know that $_POST['containerNumber'] can have multiple container numbers assigned to it.
What I need to do is extract each container number from the POST so that I can run a mysql INSERT statement per each container number.
In the database table, there are multiple columns, with container_num being the column I'm trying to update (for now).
How can I turn $container into an array and retrieve each container number that has been assigned to the variable?
I know I need to utilize a FOREACH loop. With that said, there will more than likely be multiple INSERT statements that will automatically be created with the loop.
$SQL = "INSERT INTO myTable (container_num) VALUES ('$container')";
// times however many containers the variable $container had stored in it
Please help.
EDIT **
Once the user checks however many checkboxes, I can display each container like this:
<INPUT name="containerNumber" id="containerNumber" class="containerNumber" />
When I do this, it can be displayed to the screen like this:
CONT_ID001, CONT_ID002, CONT_ID003...
I hope this helps.
There are multiple ways of doing this.
1) Give the POST parameters you're sending a name that ends with [], PHP automatically assigns them to an array when parsing the POST data. If you're sending the data from an HTML form, this is an example of how to do it:
<form action="" method="POST">
<label>
First container number:
<input type="text" name="containerNumber[]" />
</label>
<label>
Second container number:
<input type="text" name="containerNumber[]" />
</label>
<input type="submit" />
In PHP you can just do
foreach($_POST["containerNumber"] as $container) {
...
}
(Note that this is a feature of PHP and not portable to other server-side langages. This is NOT part of the HTTP specification.)
2) Separate values using some separator, in PHP use explode() to split it.
3) Send the form as JSON or encode that one field as JSON (if sent from HTML, I suggest using jQUery to do either option, as it's the easiest way) and use json_decode() in PHP to extract the contents.
4) Sevaral other options that may be suitable, depending on what exactly you're doing.
If I get you, you have a $_POST variable with multiple values.
If the content of $_POST['containerNumber'] is CONT_ID001, CONT_ID002, CONT_ID003
You can do this:
$result = preg_split("/, /", $_POST['containerNumber']);
//the result dump will be:
//$result[0] = "CONT_ID001";
//$result[1] = "CONT_ID002";
//$result[2] = "CONT_ID003";
The insert code should looks like to (assuming that you have one column for each number):
$SQL = "INSERT INTO myTable ";
$columns = "";
$values = "";
foreach (result as $id=>$out){
$columns .= "container_$id";
$values .= "'$out'";
if (count($result) < $id+1){
$columns .= ", ";
$values .= ", ";
}
}
$SQL .= "($columns) VALUES ($values)";
If you only have container_num column it should looks like:
$SQL = "INSERT INTO myTable (container_num) VALUES ('";
$columns = "";
$values = "";
foreach (result as $id=>$out){
$values .= $out;
if (count($result) < $id+1){
$values .= ", ";
}
}
$SQL .= "$values')";
I have an application that looks like this:
As you can see, each row contains either a group heading (the rows where there is just an input), or a ingredient form (where there is a small input, then a select, then another larger input).
I use Javascript to add the new spans. I use the following PHP to group each ingredient span into an array, determine the order (because each span can be moved to a different order), and insert into my database.
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);
for ($i = 0, $count = count($ingredientQTY); $i < $count; $i++) {
$rows[] = array(
'ingredientamount' => $ingredientQTY[$i],
'ingredientType' => $measurements[$i],
'ingredientname' => $ingredientNAME[$i],
'recipe_id' => $recipe_id,
'order' => $i + 1,
'user_id' => $user_id
);
$sql = "INSERT `ingredients` (`ingredientamount`,`ingredientType`,`ingredientname`, `recipe_id`, `order`, `user_id`) VALUES ";
$coma = '';
foreach ($rows as $oneRow) {
$sql .= $coma."('".implode("','",$oneRow)."')";
$coma = ', ';
}
}
$this->db->query($sql);
break;
}
This works wonders for inserting the ingredient rows. But I'm not sure how to insert group headings (which must be placed in the for loop to keep the order, the $i + 1, going).
I think I've figured out two solutions(though there may be others, and these might not even work):
Have the group heading input field have the same name value as one of the ingredient text fields, and send a hidden value along with it, saying its a group heading?
Send it as different input field with a different name value?
My question is: how can I do this with my current code, and are either of these efficient solutions, or is there an even better solution?
Thanks for all help! If you need more details, just ask!
You could use an empty heading like <input type="hidden" name="groupheading[]" value="product" /> and the open one like <input type="text" name="groupheading[]" value="" />. The first one should be inside the product-span.
This way, you can continue your loop just the way you are doing now. And $_POST['groupheading'][$key] either returns a groupheading or the phrase 'product'. So, in your script it would be:
if($_POST['groupheading'][$key] == "product") {
// insert product
} else {
// insert group heading
}
I think I helped you this morning or yesterday with an answer.. it's still a bit a weird way you are using to get the effect you need. It can be achieved much easier.
I have a dynamic web form that creates text after the user tells it how many he wants, what I want to do, is to get the info of those text fields into the next form, I've read a question that is
pretty much what I want to do;
But I haven't had any luck so far;
for ($i = 1; $i <= $quantity; $i++) {
echo "<input type='text' class='text' name='classEmpleado[]' id='empleado$i' />";}
When I try to retrieve them I use this;
$empleado[] = $_POST['classEmpleado[]'];
$i = 0;
for ($i = 1; $i <= $quantity; $i++) {
echo "$empleado[$i]<BR><BR>";
}
But I get the error Undefined index: classEmpleado[]
What am I doing wrong?
ANSWERED!
For anyone looking for the same thing, look at the response of Sherbrow,
And you would just have to edit the loop to this
$empleado[] = $_POST['classEmpleado[]'];
$i = 0;
for ($i = 0; $i < $quantity; $i++) {
echo "$empleado[$i]<BR><BR>";
}
If $empleado is not previously declared or just empty, you are looking for that
$empleado = $_POST['classEmpleado']
But if $empleado is an array, and contains data, you may want to merge everything in one only array
$empleado = array_merge($empleado, $_POST['classEmpleado']);
Whichever way you choose, there should be a check to be certain that $_POST['classEmpleado'] is defined and is an array. Something like :
if(isset($_POST['classEmpleado']) && is_array($_POST['classEmpleado'])) {
/* ... */
}
Try $empleado[] = $_POST['classEmpleado'];
When you put name[] at the end of the fieldname, it will be passed to PHP as an array in $_POST with the key of name like so: $_POST['name'] = array(1,2,3,4);
This statement here is wrong ($empleado[] = $_POST['classEmpleado[]'])
If you want to access $_POST the input field named classEmpleado[], you have to do so :
for($i=0; $i<count($_POST['classEmpleado']); $i++)
{
echo $_POST['classEmpleado'][$i] . '<br /><br />';
}
I wasn't sure what to title this question. Here's my goal:
On page one, I have a form that is generated from the database. It loops through assigning a counting variable to the id of the fields (ie: header_1, header_2, header_3...)
Now, the amount of fields may vary as I need the ability to add extra information (ie: header_4, header_5).
When I submit my form, how can I create a variable for each field?
$header1 = $_POST['header_1']
Essentially, I am looking for an array-based (or variable variable-based) way of simplifying something like this:
$sql="UPDATE about SET about_header = '$head1', about_content = '$post1' WHERE about_id = '$id1'";
$result = mysql_query($sql);
$sql="UPDATE about SET about_header = '$head2', about_content = '$post2' WHERE about_id = '$id2'";
$result = mysql_query($sql);
$sql="UPDATE about SET about_header = '$head3', about_content = '$post3' WHERE about_id = '$id3'";
$result = mysql_query($sql);
I imagine a query like this would work but I'm not sure how to handle the array of information that I would need help building as well.
$y=1;
$sql="UPDATE about SET about_header = '$head$y', about_content = '$post$y' WHERE about_id = '$id$y'";
I hope I explained this well enough. Any help would be great. Thanks!
have you ever tried something like:
<input name="header[]" />
<input name="header[]" />
<input name="header[]" />
This will create a multi-dimensional array on the PHP side which you can easily cycle through.
echo $_POST['header'][0];
echo $_POST['header'][1];
echo $_POST['header'][2];
It would also be faster to use prepared statements for this, although you would have to switch to using something like PDO for your database interactions. Here's an example of looping thorugh using the code you showed above.
$fieldCount = count($_POST['header']);
for ($i = 0; $i < $fieldCount; $i++) {
$sql = 'UPDATE about SET about_header = \''.$_POST['header'][$i].'\', about_content = \''.$_POST['post'][$i].'\' WHERE about_id = \''.$_POST['id'][$i].'\'';
mysql_query($sql);
}
<input type="text" name="head[]" />
<input type="text" name="head[]" />
<input type="text" name="head[]" />
<?php
foreach ($_POST['head'] as $head) {
// ....
}
?>
Naming your inputs like this (note the array-ish notation) will yield
$_POST == array( 'head' => array(
0 => FIRST TEXT DATA,
1 => SECOND TEXT DATA,
2 => THIRD TEXT DATA
))
i noticed that when posting a form the fields come out as an array.
like if i do
if(isset($_POST['submit'])) {
print_r($_POST);
}
what i usually do for form fields is the following.
lets say i have something like this (this is how i usually do it)
<form method="POST" action="">
<label>First Name: </label>
<input type="text" name="fname">
<label>Last Name: </label>
<input type="text" name="lname">
<label>Phone: </label>
<input type="text" name="phone">
<input type="submit" name="submit" value="submit">
</form>
then i'll have (im excluding field validation to make it look clear)
if(isset($_POST['submit'])) {
$fname = $_POST['fname'];
$lname = $_POST['lname'];
$phone = $_POST['phone'];
mysql_query("insert into table(fname,lname,phone) values('$fname','$lname','$phone')");
header("Location: gosomewhere.php");
}
since the post outputs are in an array format how else can i write this when im dealing with over 100 fields?
how are the big guys doing it out there? or how are you doing it?
edit: the most ive dealth with is around 60 fields. im building this cms that takes in alot of data per form to put together information from a customer.
I don't think I've ever seen anybody "dealing with over 100 fields" in a single form. If that is the case, you may consider a design-change that auto-saves portions of the data along the way. Form data will always submit itself into an array on the server-end, there's no way around this.
If you want to iterate over many fields all at once (suppose you are accepting multiple event-dates in your form), you could use the array-style naming-convention:
<input type="text" name="events[]" />
Once you access this data on the server end, you can iterate over it quickly in a simple loop:
foreach ($_POST["events"] as $event) {
echo $event;
}
I'm sorry if I missunderstood your question.
As Jonathan said, 100 fields in one form is way to much. But you can always build the SQL dynamically.
E.g:
if(isset($_POST['submit'])) {
// allow only entries that are database fields
$allow = array(/*whatever*/);
$fields = array();
$values = array();
foreach($_POST as $field => $value) {
if(in_array($field, $allow) {
// Do correct output escaping etc. here !!
$fields[] = $field;
$values[] = mysql_real_escape_string($value);
}
}
mysql_query('insert into table(' . join(',', $fields) . ' values(' . join(',', $values) . ')');
}
This assumes that your form fields names are the same as your DB column names.
If, as Cyro says, array_keys and array_values preserve order, then this can be done even nicer:
function clean($value, $field, &$params) {
if(in_array($field, $params['allow']) {
// custom validation goes here
$params['data'][$field] = mysql_real_escape_string($value);
}
}
if(isset($_POST['submit'])) {
// allow only entries that are database fields
$allow = array(/*whatever*/);
$params = array('allow' => $allow, 'data' => array());
array_walk($_POST, 'clean', $params);
if(!empty($params['data'])) {
mysql_query('insert into table(' . join(',', array_keys($params['data'])) . ' values(' . join(',', array_values($params['data'])) . ')');
}
}
See array_walk
If your form contains over 100 fields, I'd worry much more about the client side than the server side. Consider using something like jQuery UI Tabs to split the form up into multiple areas, separated using fieldsets, to enhance usability.
One way around the array issue would be to use something like PHP's extract function, but I wouldn't recommend this for security reasons, and because it wouldn't really make the data any easier to work with.
The best way of dealing with so many fields is to reduce the number of fields. No one wants to have to fill out scores of fields.
Failing that, PDO has much to offer by supporting prepared statements. One thing are parameters, which (unlike your sample code) aren't vulnerable to SQL injection. Parameters can also be used to more easily construct a query using values from an array.
$query = $db->prepare("INSERT INTO table (surname, given_name, main_phone, ...)
VALUES (:fname, :lname, :phone, ...)");
$values = array()
foreach($_POST as $key => $val) {
$values[':' + $key] = $val;
}
try {
$query->execute($values);
} catch (PDOException $exc) {
...
}
The list of column names can be defined elsewhere, or automatically generated, then imploded when creating the prepared statement.
If your form field names directly relate to your database table columns you can dynamically build your query from the $_POST array. From your example you could do:
$allowed_fields = array('fname', 'lname', 'phone');
foreach($_POST as $key => $value) {
// if this isn't an expected field (user-injection) ignore it
if(!in_array($key, $allowed_fields))
continue;
// do validation checks and data clean up here in a switch
$data[$key] = mysql_real_escape_string($value);
}
mysql_query("INSERT INTO table(`" . implode('`, `', array_keys($data)) . "`) VALUES('" . implode("', '", array_values($data)) . "')");
Really though, a form with 100+ fields is not something I would ever fill out and I don't believe I'm alone in that. Consider breaking it up into multiple steps as others have suggested or try re-approaching your initial design.