423,309 Members | 2,460 Online
Bytes IT Community
Submit an Article
Got Smarts?
Share your bits of IT knowledge by writing an article on Bytes.

Using HTML Forms to pass data to PHP

Atli
Expert 5K+
P: 5,058
Introduction
At some point, all web developers will need to collect data from their users. In a dynamic web page, everything revolves around the users input, so knowing how to ask for and collect this data is essential to any developer.
This article is a basic tutorial on how to user HTML Forms, the most common method of data collection.

Assumptions
- Basic HTML knowledge.
- Basic PHP knowledge.

HTML Forms
A common and simple way of gathering data is through HTML Forms. Forms are containers for user input and can contain any number of different input types.
The HTML form element requires a few parameters to work properly:
  • action: this should point to the page that is meant to process the collected data. As soon as the form is submitted, the browser is redirected to this location, along with all your data.
  • method: this is the method of transportation. There are two choices here: 'GET' and 'POST'. I will cover them both in the next chapter.
A typical form element might look like this:
Expand|Select|Wrap|Line Numbers
  1. <form id="Form1" action="submit.php" method="post">
  2. <!-- Input elements will be put here -->
  3. </form>
  4.  

The data delivery methods, GET and POST.
As you may have guessed from the names of the two protocols, the GET and POST requests are designed for different purposes.

The purspose of the GET protocol is to fetch and display data to the user. Simple key-value pairs can be passed via the query string, but they should ideally be used to specify what should be displayed on the page, rather than to push user data onto the server.

That is what the POST protocol is for. It is designed to allow clients to send pretty much any amount of data to the server, in pretty much any format. This is what most forms should be using, and it is required for things like file uploads and to upload large amounts of text.

Essentially, GET should be used for navigation and things of that nature, but POST should be used to send actual data. Now lets examine them in more detail, individually.

The GET protocol
When using GET, the data from the form is encoded into the URL of the request. For example, if you were to submit this form:
Expand|Select|Wrap|Line Numbers
  1. <form action="action.php" method="get">
  2.     <input type="text" name="Username" value="John"><br>
  3.     <input type="password" name="Password" value="thePassword"><br>
  4.     <input type="submit">
  5. </form>
When you hit the submit button, the browser would redirect you to this URL:
- action.php?Username=John&Passsword=thePassword

A very usefult aspect of the GET protocol is the fact that we do not have to use a form to submit GET data. The URL can be manually constructed as well, and the server will not see any difference. Which means that the above data can also be submitted using the following HTML link:
Expand|Select|Wrap|Line Numbers
  1. <a href="action.php?Username=John&Passsword=thePassword">Submit</a>
This can be extremely usefuel in websites that show dynamically created content, such as forums or blogs, where you often need to create dynamic navigation links. In fact, this is used in most dynamic web 2.0 applications out there.

The POST protocol
The data submitted via the POST protocol is not visible in the URL. The data itself is put into the body of the request, which allows POST requests to upload more data, and more complex data, than the GET request.

For example, to send a username and an image, you would use a form like this:
Expand|Select|Wrap|Line Numbers
  1. <form action="action.php" method="post" enctype="multipart/form-data">
  2.     <input type="text" name="Username"><br>
  3.     <input type="file" name="UserImage">
  4.     <input type="submit">
  5. </form>
You will notice there that an additional attribute has been added to the form. The "enctype" attribute is required when sending files. If it is missing, the files will not be sent. - This attribute simply tells the client how to format the body of the request. By default it is a fairly simple format, but to send a binary object, a more complex one is required.

The <input> element
Like all forms, HTML forms need fields for the user to fill out. This is what the <input> element is for.
Input elements are positioned inside the <form> element, and can be used as a number of different types of fields. The type is set by chaning the "type" attribute of the field to one of the following values:
  • text: This is a simple text box. Allows users to input any text.
  • password: This is similar to the "text" input, except this is meant for passwords. The text is obfuscated, so the actual text you type into it is not visible. (Usually by replacing each character with an asterisk.)
  • button: This creates a button. It has no special purpose. It's mostly used to execute JavaScript code.
  • submit: This forms a button that when clicked, submits the form. If you specify a name and a value, they will be included in the data. Otherwise not.
  • reset: This forms a button that resets all the fields in the form. Use with caution!
  • checkbox: This creates a checkbox. Only boxes that have been checked will be sent along with the data. Unchecked boxes will be disregarded.
  • radio: This creates a radio button. If you create a number of these with the same name, only one of them can be selected at any given time, and only the selected one will be included with the data. The "value" attribute of the selected box will be sent.
  • hidden: This field is not displayed. It is hidden, but its value will be sent. These are highly useful when you need to include a value from your PHP or JavaScript code, but don't want it visible to the user.
  • file: This type allows a file to be selected and uploaded to the server.
A simple example of a form populated with input elements:
Expand|Select|Wrap|Line Numbers
  1. <form id="Form1" action="submit.php" method="post">
  2.   Username: <input type="text" name="Username"><br>
  3.   Password: <input type="password" name="Password"><br>
  4.   Remember me: <input type="checkbox" name="Remember" checked="checked">
  5.   <input type="hidden" name="SubmitCheck" value="sent">
  6.   <input type="Submit" name="Form1_Submit" value="Login">
  7. </form>
Reading the form data
To read the data submitted by a form, using PHP, we use one of three special arrays. Those are: $_GET, $_POST or $_REQUEST. The first two contain the data submitted via their respective protocols. The third, $_REQUEST contains the data from both.

The index(key) of the array is the name property of the input element. So if we were to send the form we created earlier, we could print the Username you passed like this:
Expand|Select|Wrap|Line Numbers
  1. echo $_POST['Username'];
If you are lazy you can just call "$_REQUEST['Username']" instead, but it comes at a price. Depending on your PHP configuration either the $_GET or $_POST array supersedes the other, overriding duplicate values. That means that if both the POST and GET protocols send a value with the same name, one of them will not be available, and you risk using the incorrect value in your code. - And to make matters worse, the Cookie and Enviromental variables are also thrown into the mix, increasing the risk even further.

The moral of this story is: use the $_GET and $_POST arrays, rather than the $_REQUEST array. It's safest that way.

Using the collected data
Before we finish, let's make a simple example, using our login form from before.

This form tests for the username 'John' and the password 'Doe' and responds accordingly. - Note, that I have changed the 'action' property of the form to point to itself, which will cause the page to reload, along with the data.
Expand|Select|Wrap|Line Numbers
  1. <?php
  2. /**
  3.  * WARNING!
  4.  * This EXAMPLE code contains severe SECURITY ISSUES
  5.  * which should be addressed before real-life usage!!
  6.  *
  7.  * These issues have been ignored intentionally to
  8.  * simplify the code so we can focus on the topic
  9.  * in discussion.
  10.  */
  11.  
  12. // Lets test if the form has been submitted
  13. if(isset($_POST['SubmitCheck'])) {
  14.     // The form has been submited
  15.     // Check the values!
  16.     if($_POST['Username'] == "John" and $_POST['Password'] == "Doe") {
  17.         // User validated!
  18.         echo "Thats right! You have been logged in!";
  19.  
  20.         // Check if the checkbox was checked
  21.         if(isset($_POST['Remember'])) {
  22.             echo "<br>You will be remembered!";
  23.         }
  24.         else {
  25.             echo "<br>John who?!";
  26.         }
  27.     }
  28.     else {
  29.         // User info invalid!
  30.         echo "Sorry mate, try again!";
  31.     }
  32. }
  33. else {
  34.     // The form has not been posted
  35.     // Show the form
  36. ?>
  37. <form id="Form1" action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">
  38.     Username: <input type="text" name="Username"><br>
  39.     Password: <input type="password" name="Password"><br>
  40.     Remember me: <input type="checkbox" name="Remember" checked="chekced">
  41.     <input type="hidden" name="SubmitCheck" value="sent">
  42.     <input type="Submit" name="Form1_Submit" value="Login">
  43. </form>
  44. <?php
  45. }
  46. ?>
  47.  
The finish line
So, thats it for my basic article on HTML Forms.

A final warning!
Use data posted through HTML Forms carefully.
Always assume the data you receive is somehow meant to damage your web and validate it accordingly!

Remember that your web is only as good as the information it displays, so make sure your data is in order.

All the best,
- Atli r
Jun 18 '07 #1
Share this Article
Share on Google+
19 Comments


P: 1
Good Codeing for
Creat login Id using html in php
Dec 5 '07 #2

P: 3
Good tutorial, but this is incredibly important... (to the readers, not to the author, lol)you may have heard that $_GET poses a security risk, but it is technically no bigger than $_POST. With a basic understanding of web development, the firefox web developer toolbar, and a few minutes, a malicious user can easily pass any value he/she wants through that POST value.

the moral of the story, NEVER TRUST DATA COMING FROM THE USER!!! This rule is absolute, I dont care if the only user is the tech guy that works at your office, any data from any user has to be taken with a grain of salt.

That said, it is rather easy to sterilize data

Expand|Select|Wrap|Line Numbers
  1. function sterilize (&$sterilize=NULL) {
  2.     if ($sterilize==NULL) {return NULL;}
  3.     $check = array (1 => "'", 2 => '"', 3 => '<', 4 => '>');
  4.     foreach ($check as $value) {
  5.         $sterilize=str_replace($value, '', $sterilize);
  6.     }
  7.     $sterilize=strip_tags ($sterilize);
  8.     $sterilize=stripcslashes ($sterilize);
  9.     $sterilize=stripslashes ($sterilize);
  10.     $sterilize=addslashes ($sterilize);
  11.     return $sterilize;
  12. }
now, imagine the user is entering his name, so $_POST['name']='Jason', all you would have to do is call the function above like this:
$Name=sterilize($_POST['name']);

the data, although not fighting against any sql injections (have another function for that), will clean the data of any tags, slashes, and escapes.

edit: just wanted to add a little bit, not trusting data isnt just for text boxes and fields, but also for drop down boxes, and even lowly checkboxes and radio buttons

(note, I know I am passing the var by ref, but it is just easier to set it to an easy to remember var and sanitize in the same step)
Dec 18 '07 #3

P: 1
Good tutorial, but this is incredibly important... (to the readers, not to the author, lol)you may have heard that $_GET poses a security risk, but it is technically no bigger than $_POST. With a basic understanding of web development, the firefox web developer toolbar, and a few minutes, a malicious user can easily pass any value he/she wants through that POST value.

the moral of the story, NEVER TRUST DATA COMING FROM THE USER!!! This rule is absolute, I dont care if the only user is the tech guy that works at your office, any data from any user has to be taken with a grain of salt.

That said, it is rather easy to sterilize data

Expand|Select|Wrap|Line Numbers
  1. function sterilize (&$sterilize=NULL) {
  2.     if ($sterilize==NULL) {return NULL;}
  3.     $check = array (1 => "'", 2 => '"', 3 => '<', 4 => '>');
  4.     foreach ($check as $value) {
  5.         $sterilize=str_replace($value, '', $sterilize);
  6.     }
  7.     $sterilize=strip_tags ($sterilize);
  8.     $sterilize=stripcslashes ($sterilize);
  9.     $sterilize=stripslashes ($sterilize);
  10.     $sterilize=addslashes ($sterilize);
  11.     return $sterilize;
  12. }
now, imagine the user is entering his name, so $_POST['name']='Jason', all you would have to do is call the function above like this:
$Name=sterilize($_POST['name']);

the data, although not fighting against any sql injections (have another function for that), will clean the data of any tags, slashes, and escapes.

edit: just wanted to add a little bit, not trusting data isnt just for text boxes and fields, but also for drop down boxes, and even lowly checkboxes and radio buttons

(note, I know I am passing the var by ref, but it is just easier to set it to an easy to remember var and sanitize in the same step)
while I agree with you on never trusting user-supplied data, I completely disagree with you on relying on sanitation. Sanitation will NEVER be able to completely insulate you from an attack as someone will ALWAYS be able to evade your filters (which is essentially what you are doing with your sanitation routine). User-supplied data should always be VALIDATED, and validation != sanitation. You can certainly do both (validation and sanitation), but NEVER rely on sanitation only.

For example, a user name is most likely comprised of alpha characters and maybe digits. If that is the case, then you check to make sure that what the user supplied is ONLY alpha/num characters
Expand|Select|Wrap|Line Numbers
  1. if(ctype_alnum($_POST['Username'])){
  2.     //continue with log in process
  3. } else {
  4.     //refuse the login
  5. }
If you need additional characters in the user name, then build a regex pattern, and compare the user-supplied data to the pattern. If it fails, dont go any farther.

Furthermore, you should hash the password in storage, then compare the hash of the user-supplied password to what you have in storage:
Expand|Select|Wrap|Line Numbers
  1. if(sha1($_POST['Password']) == $usersStoredHashedPassword){
  2.     //continue with login process
  3. } else {
  4.     //refuse login
  5. }
Last, before echo'ing back ANY user-supplied data to the browser, ALWAYS encode it first!

oh, and absentmindedjwc, the contact me form on your website is susceptible to XSS injection. ;)
Dec 18 '07 #4

P: 1
What is the advantage of using the _GET and _POST arrays versus the variables that get automatically created when the form is submitted.

For example, if I have a form with the input variable "Username", why should I bother to refer to this as $_POST['Username'] rather than $Username?
Dec 18 '07 #5

P: 3
oh, and absentmindedjwc, the contact me form on your website is susceptible to XSS injection. ;)
I noticed, :/

a variant of what I have currently on the site, and what I posted here (among a couple other things) are going into the redesign of my site. Using JUST what I have up there clears up every XSS injection that I threw at it...

BTW: closed the hole ;)
Dec 18 '07 #6

P: 3
What is the advantage of using the _GET and _POST arrays versus the variables that get automatically created when the form is submitted.

For example, if I have a form with the input variable "Username", why should I bother to refer to this as $_POST['Username'] rather than $Username?
either I am misunderstanding your question, or you are misunderstanding how GET and POST arrays work... when you push submit, the data gets sent to the server as either a GET or a POST, depending on the method of the form. $username will not be set unless you set it, the variable $_POST['username'], on the other hand, will be set.
Dec 18 '07 #7

pbmods
Expert 5K+
P: 5,821
What is the advantage of using the _GET and _POST arrays versus the variables that get automatically created when the form is submitted.

For example, if I have a form with the input variable "Username", why should I bother to refer to this as $_POST['Username'] rather than $Username?
Heya, RalphSlate.

You're talking about register_globals, which is being discontinued in PHP 6.

register_globals is convenient, but it actually encourages you to write insecure code. Have a look at this page.
Dec 19 '07 #8

Atli
Expert 5K+
P: 5,058
I completely agree with you about the data validation and sanitation.
All data you received using HTML forms, such as the one discussed in the article, should always, without exception, be considered dangerous until proven safe.

There are of course many different methods of validating and securing user input, each with it's uses and limitations. PHP does provide a few very handy functions that help deal with user input, such as the htmlspecialchars function and the htmlentities function.

To be as safe as possible, it would be best to go with a "white-list" approach, which essentially goes through the input and removes all characters that have not be approved.

The opposite method would be a "black-list" approach, which would remove only those characters you have listed. This is naturally less secure but does not run the risk of removing excess data.

As the the question of $_POST['var'] vs $var...

As pbmods mentioned, the difference there is that the second variable is created by PHP if you have the register_globals directive enabled in the PHP configuration.

As of PHP 5, this is disabled by default and if I am not mistaken this option will be completely removed in PHP 6, as it does create a possible security risk. Details on that can be found in the link pbmods posted.
Dec 26 '07 #9

P: 1
As of PHP 5, this is disabled by default and if I am not mistaken this option will be completely removed in PHP 6, as it does create a possible security risk. Details on that can be found in the link pbmods posted.
I always use extract($POST); as an early line in my scripts. It reads all $POST[variables] into $variables. The only caveat is to avoid using the same names for locally declared variables.
Mar 18 '08 #10

Atli
Expert 5K+
P: 5,058
I always use extract($POST); as an early line in my scripts. It reads all $POST[variables] into $variables. The only caveat is to avoid using the same names for locally declared variables.
This is essentially the exact same thing being done when the register_globals directive is enabled. The only difference would be that this way neither the $_GET nor the $_SESSION super-globals are being serialized into the global scope.

As pbmods says, this can be convenient but it does open up a possible security risk. All request data should, with no exceptions, be treated as harmful until proven safe. This method is essentially importing possibly harmful data into your global scope, which is obviously something you should avoid.
Mar 19 '08 #11

Markus
Expert 5K+
P: 6,050
Dugg.

Nice read.

:)
May 25 '08 #12

acoder
Expert Mod 15k+
P: 16,027
Dugg.
Erm...wasn't this already dugg back in December last year?
Jun 2 '08 #13

P: n/a
Kathy Li
very clear, very practical, and very very helpful tutorial.
Oct 18 '10 #14

P: 1
From a book I was using, a POST method was suggested for an order form.
When it came to coding the php file for outputing the results from the order form, it gave the following syntax:
echo $tireqty." tires";
it only displayed "tires" and not the amount (variable).
The syntax is based on php v4 and I am using php v5 could there be a change with the syntax?
Otherwise I am trying out what's been suggested. Very good tutorials.
Jan 7 '11 #15

AutumnsDecay
100+
P: 170
You need to set the variable on the next page, it's not automatically set for you.

Page1:
Expand|Select|Wrap|Line Numbers
  1. <input type="text" name="qty" />
  2.  
Page2:
Expand|Select|Wrap|Line Numbers
  1. $qty = $_POST['qty'];
  2.  
Jan 8 '11 #16

P: 9
What is the solution of stop submission of form on refresh, I am trying lot of tips and tricks, some of them works but I am not satisfied with them. If you have any clean solution please update.
Regards,
Mangal Kumar
Oct 15 '11 #17

zorgi
Expert 100+
P: 431
Redirection after submission will do the trick.
Oct 15 '11 #18

P: 3
Thank you for this article. It resolved a problem that I have had for days.
Jan 7 '12 #19

P: 4
Variable Data passing between PHP, HTML, JAVASCRIPT

Expand|Select|Wrap|Line Numbers
  1. <?php  $xphp= "My PHP WORLD"; ?>   <!-- Define a PHP variable -->
  2. <script> var xjs='My Java Script world'; </script> <!-- Define a JAVASCRIPT variable -->
  3. <input type='hidden' id='myhtml' value='My HTML world!' > <!-- Define a HTML variable -->
  4.  
  5. <BR>sending PHP variable value into JAVASCRIPT <BR>
  6. <script>
  7. var xphp='<?php echo $xphp; ?>';
  8. document.write(xphp);    
  9. </script>
  10.  
  11. <BR>getting PHP variable value into HTML <BR>
  12. <?php echo $xphp; ?>
  13.  
  14. <BR><BR>getting JAVASCRIPT  variable value into PHP <BR>
  15. <?php
  16. $xjs = "<script>document.write(xjs);</script>";
  17. echo $xjs;
  18. ?>
  19.  
  20. <BR>getting JAVASCRIPT  variable value into HTML <BR>
  21. <script>document.write(xjs);</script>
  22.  
  23. <BR><BR>getting HTML variable value into JAVASCRIPT  <BR> 
  24. <script>
  25. var xhtml=document.getElementById('myhtml').value;
  26. document.write(xhtml);    
  27. </script>
  28.  
  29. <BR>getting HTML variable value into PHP <BR> 
  30. <?php
  31. $xhtml = "<script>document.write(document.getElementById('myhtml').value);</script>";
  32. echo $xhtml;
  33. ?>
Mar 27 '17 #20