Using HTML Forms to pass data to PHP
Written by Atli, June 18th, 2007
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:
Code: ( text )
<form id="Form1" action="submit.php" method="post"> <!-- Input elements will be put here --> </form>
GET & POST
The methods used to transport the data from our forms to the server are called GET and POST.
For simple text forms, both of them will work fine. But for more complex data, such as Unicode text and files, the GET protocol can not be used.
When using the GET protocol, the form data is transported via the URL string.
That is to say; each variable, accompanied by it's data, is added to the URL.
Because of this, the GET protocol can only transport characters that can be encoded into the URL, and can not exceed the maximum characters allowed in an URL string.
This is how a typical URL string may look when using the GET protocol.
Code: ( text )
http://www.example.com/page.php?fname=John&lname=Doe
The POST protocol uses the HTTP request itself to transport the data.
The result of this is that the data itself is not visible to the user, and this allows us to transport large amounts of data, including binary data.
I would recommend using this method rather than the GET method with very few exceptions.
Most modern HTTP servers are able to process requests that contain both methods at the same time (some older versions of IIS do not however), which can be useful at times.
Either of these two can be intercepted and read by most novice hackers, so never assume unencrypted data is safe.
Be careful when submitting sensitive data, and try to take extra security measures when possible.
The Input element
As all forms do, HTML forms need fields that need to be filled. That is what the input element is for.
Input elements are positioned inside the form element, and can be used as a number of different fields: - Text: This input forms a simple textbox.
- Password: This is like the Text input, except all letters are hidden, using * signs.
- Button: This creates a simple button. Mostly used to trigger scripts.
- Submit: This also creates a button, except when this button is clicked, the form is submitted.
- Reset: Like the submit type, this is a button. When clicked, this button resets all input fields in the form.
- Checkbox: This creates a checkbox. Only boxes that have been checked will be sent along with the data. Unchecked boxes will be disregarded.
- Radio: 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.
- Hidden: This field is not displayed. It is hidden, but its value will be sent. These can be highly useful when populating forms using scripts.
A simple example of a form populated with input elements:
Code: ( text )
<form id="Form1" action="submit.php" method="post"> Username: <input type="text" name="Username" /><br /> Password: <input type="password" name="Password" /><br /> Remember me: <input type="checkbox" name="Remember" checked="checked" /> <input type="hidden" name="SubmitCheck" value="sent" /> <input type="Submit" name="Form1_Submit" value="Login" /> </form>
Reading the form data
All right! Now we have a form, all we need to do know is read the data. To do that we are going to use PHP.
PHP contains these three arrays; $_GET, $_POST and $_REQUEST.
The first two are pretty transparent. The third, however is different.
The $_GET and $_POST arrays contain all the data sent using either the GET or the POST methods. Logically, the $_GET array contains GET data, and the $_POST array the POST data.
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:
'echo $_POST['Username'];'
The $_REQUEST array is a little different than the other two.
It contains both GET and POST data, so if your lazy you can just call "$_REQUEST['Username']" instead of $_GET or $_POST.
Note, that depending on your PHP configuration, either the $_GET or $_POST array (aswell as the $_COOKIE array) supersedes the other, overriding duplicate values. So it is safest to always use $_GET or $_POST
Using the collected data
So before we finish this, 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.
Code: ( text )
<?php ### # Warning! # This code contains severe security issues # which should be addressed before real-life usage. # # These issues have been ignored intentionally to # simplify the code so we can focus on the topic # in discussion. # # They are a subject of a much more advanced # topic than the one covered in this article. ### // Lets test if the form has been submitted if(isset($_POST['SubmitCheck'])) { // The form has been submited // Check the values! if($_POST['Username'] == "John" and $_POST['Password'] == "Doe") { // User validated! echo "Thats right! You have been logged in!"; // Check if the checkbox was checked if(isset($_POST['Remember'])) { echo "<br />You will be remembered!"; } else { echo "<br />John who?!"; } } else { // User info invalid! echo "Sorry mate, try again!"; } } else { // The form has not been posted // Print the form echo <<<END <form id="Form1" action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post"> Username: <input type="text" name="Username" /><br /> Password: <input type="password" name="Password" /><br /> Remember me: <input type="checkbox" name="Remember" checked="chekced" /> <input type="hidden" name="SubmitCheck" value="sent" /> <input type="Submit" name="Form1_Submit" value="Login" /> </form> END; } ?>
The finish line
So, thats it for my extremely 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.
Me or one of my fellow developers here at TSDN will most like be posting an article on input validation in the near future, so stay tuned!
- Atli Þór
Last edited by Atli : Yesterday at 05:57 AM.
Reason: Updated the GET & POST section.
Good Codeing for
Creat login Id using html in php
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
Code: ( text )
function sterilize (&$sterilize=NULL) { if ($sterilize==NULL) {return NULL;} $check = array (1 => "'", 2 => '"', 3 => '<', 4 => '>'); foreach ($check as $value) { $sterilize=str_replace($value, '', $sterilize); } $sterilize=strip_tags ($sterilize); $sterilize=stripcslashes ($sterilize); $sterilize=stripslashes ($sterilize); $sterilize=addslashes ($sterilize); return $sterilize; }
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)
Jason Corradino
Web Designer and Developer
JasonCorradino.com
(sorry for the shameless promotion link, but this was dugg, great for google juice and SEO, lol)
tenest /
December 18th, 2007 07:42 PM
Quote:
Originally Posted by absentmindedjwc
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
Code: ( text )
function sterilize (&$sterilize=NULL) { if ($sterilize==NULL) {return NULL;} $check = array (1 => "'", 2 => '"', 3 => '<', 4 => '>'); foreach ($check as $value) { $sterilize=str_replace($value, '', $sterilize); } $sterilize=strip_tags ($sterilize); $sterilize=stripcslashes ($sterilize); $sterilize=stripslashes ($sterilize); $sterilize=addslashes ($sterilize); return $sterilize; }
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
Code: ( text )
if(ctype_alnum($_POST['Username'])){ //continue with log in process } else { //refuse the login }
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:
Code: ( text )
if(sha1($_POST['Password']) == $usersStoredHashedPassword){ //continue with login process } else { //refuse login }
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. ;)
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?
Quote:
Originally Posted by tenest
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 ;)
Quote:
Originally Posted by RalphSlate
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.
pbmods /
December 19th, 2007 10:15 AM
Quote:
Originally Posted by RalphSlate
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.
Atli /
December 26th, 2007 01:30 AM
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.
nstone /
March 18th, 2008 02:19 AM
Quote:
Originally Posted by Atli
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.
Atli /
March 19th, 2008 10:49 PM
Quote:
Originally Posted by nstone
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.
acoder /
June 2nd, 2008 09:30 AM
Quote:
Originally Posted by markusn00b
Dugg.
|
Erm...wasn't this already dugg back in December last year?
|
|
|
|
Stats:
Views: 22824
Comments: 12
|
|