UNIT 3: Handling HTML Forms
Unit Objectives
By the end of this unit, you will be able to,
- access the data sent through the html form
- utilize superglobal variables in handling PHP documents
- debug the problems that occur as a result of unfilled/unchecked/not selected form elements
- escape single/double quotation marks that may exist within the input submitted by the user
- remove the single/double quotation marks before they are displayed back on the web browser
- utilize "if" conditionals in handling PHP documents
- utilize "else" conditionals in handling PHP documents
- utilize "elseif" conditionals in handling PHP documents
- utilize "NOT (!)" operators
- utilize the comparison operators in "if, elseif, and else" conditional statements
- evaluate whether a textfield/textarea form element was submitted without a value or not
- evaluate whether a radio button, checkbox, pull down menu, or a scroll down list form element was submitted without a value or not
- turn on the server's display errors settings
- set the error reporting level
Handling HTML Forms
registration_handle.inc.php. 'registration_handle.inc.php' and 'registration.inc.php' will be stored in the same folder called 'includes'. In this unit,
registration_handle.inc.phpwill be created to print the received data from 'registration.inc.php' on 'registration_handle.inc.php', which will then be sent back to the web server to be displayed on the browser.
Programming registration_handle.inc.php
file
Within registration_handle.inc.php
, the first thing to do is to access the data submitted through the form in registration_handle.php
. In registration_handle.php
, the action attribute of the form tag is set to 'POST'. Therefore, we will need to access the data form the $_POST superglobal variable. The names of the from elements comprises the keys of the cells in $_POST superglobal variable. Hence, if we want to access the data coming from the textfield named 'first_name', then we will refer to the cell where the data is stored as $_POST['first_name']. The keys are case sensitive, which means that you need to use them exactly the same as how they are named on form element from which the data is being retrieved.
Here is an example textfield named 'first_name' located in registration.inc.php
file:
<input type='text' name='first_name' id='first_name' />Here is how we retrieve the data coming from this 'first_name' textfield in
registration_handle.inc.phpfile:
echo 'The first name entered by the user is: '.$_POST['first_name'];
In Unit 1, you have seen and used some of the super global variables including $_SERVER[PHP_SELF
], $_SERVER[REMOTE_ADDR
], and $_SERVER[HTTP_USER_AGENT
]. $_POST['key'] is similar to those superglobal variables. These superglobal variables share a few common attribute. They are accessible everywhere within the script, the names for these superglobal variables start with a $
followed by an underscore _
sign, their names are in capital letters (i.e., $_GET[], $_POST[], $_SERVER[], $_REQUEST[], $_FILES[], $_COOKIES[], $_SESSION[]). Super global variables are structured as associative arrays.
Each cell within $_POST['key'] super global variable contains the data sent by one of the html form element. For example, $_POST['first_name'] contains the data sent through the form element named first_name
. If the user does not enter any value in this form element and if there is no default data set by the value attribute, then there will be a white space stored in $_POST['first_name'] cell for this HTML form field. This is true for text fields, text areas, date, time, datetime, color, url, search, email, number, progress, range, and password fields. However, if the user does not select any of the checkbox, radio button, or pull down menu options and if there is no default checked or selected option, then the corresponding cell for the checkbox, radio button, or pull down menu in $_POST['key'] superglobal variable will be undefined/unset.
Security Measures
HTML chars to HTML entities with htmlspecialchars()
Superglobal variables are often exploited by hackers to ruin web sites. They do this by submitting malicous code through one of the text fields including textfields, textareas, email, url, color, date, datetime, time, search, number, progress, range, or password. The malicious code may involve some HTML codes. If the HTML codes are processed, then it may cause some problems on your web site. Therefore, instead of processing the HTML codes submited by a malicous user through one of the form fields, you may want to print them on the browser, which would be a safe option. You may do this by converting HTML special characters including <, >, &, ", and ' into html entities. To do this, you will use htmlspecialchars() function. This is illustrated in the following examples,
echo htmlspecialchars("<a href='main.php'>Main Page</a>")
echo 'The first name entered by the user is: '.htmlspecialchars($_POST['first_name']);
Escaping Single/Double Quotation Marks with mysqli_real_escape_string($link, $data)
The data submitted by the user may include single or double quotation marks. For example, the user may enter O'Hare for his/her last name. In these cases, the single and double quotation marks need to be escaped because they are processed with SQL Queries in MySQL Database. Otherwise, they will break the SQL Queries, which will result in SQL errors.
However, before all data coming from the form is escaped, the auto escape setting on the server, called Magic Quotes
, needs to be checked to see if the server escapes the data automatically. If the server is set to escape them automatically, then you do not need to escape them again manually. You may check this server setting using ini_get('magic_quotes_gpc') or 'get_magic_quotes_gpc()' functions. ini_get('magic_quotes_gpc') or get_magic_quotes_gpc() functions will return either a false (0) or a true (1) indicating whether Magic Quotes
setting is disabled or enabled, respectfully.
If the Magic Quotes
setting is enabled, using stripslashes($data) function, we may get rid of the backslashes from the data automatically added by the server before the single/double quotation marks so that we may manually add them in using mysqli_real_escape_string($link, $data) function.
Here is an example:
$data = $_POST['first_name'];
if(get_magic_quotes_gpc()){
$data = stripslashes($data);
}
$data = mysqli_real_escape_string($link, trim($data));
$data will have the data, where the single/double quotation marks will be escaped by backslashes. When displaying the data back to the user on the browser, you will need to remove these single/double quotation marks using stripslashes() function as shown in the example below,
$data = stripslashes($_POST['first_name']); echo "Your first name is $data";
Using Conditionals for Validation Testing
The if Conditional Statement
I am going to use a course enrollment anology for the if
conditional statement. Some of the courses require you to take a lower level course before you cannot enroll into an upper level course. After you take the lower level prereq course, then you are allowed to take the upper level course and move on. If you do not meet the prerequisite lower-level course, then you cannot continue.
Programing flow is similar to this anology. There will always be conditionals to be met, based on the results of these conditionals, some statements are executed. One way to create these conditionals is using the 'if' statement followed by an open and closed parenthesis, within which the condition is entered, i.e. if(6==5). If the condition is met, meaning that the condition returns TRUE, soem statements are executed, which are placed within curly braces right after the closing pranthesis for the 'if' conditional, i.e. if(5==5){ echo . We already used an 'if' conditional above when checking the magic_quotes setting on the server as also seen below:
Five is equal to five
; }
if (get_magic_quotes_gpc()) {
$first_name = stripslashes($first_name);
}
$first_name = mysqli_real_escape_string($link, $first_name);
The if-else Conditional Statement
In an "if ... else" conditional statement, if the condition for the if
statement is met (TRUE), then the statements within curly braces for the if
statement is executed. On the other hand, if the condition for the if
statement is not met (FALSE), then the statements for the if
condition will not be executed. You may need to execute some other statements when the 'if' condition returns FALSE. An else
statement is created to enclose these statements that are executed when the initial 'if' condition returns 'FALSE'.
Now, let's use an else
statement in an example.
if (get_magic_quotes_gpc()){
$first_name = $_POST[first_name
];
}else{
$first_name = mysqli_real_escape_string($link, $_POST[first_name
]
In the example above, if the magic quotes setting is enabled (TRUE), then the data is already escaped by the server, we may assign the first name data from the $_POST superglobal variable directly into $first_name variable. On the other hand, if the magin quotes setting on the server is not enabled, in which case the 'if' conditional will return FALSE, then the statement for the 'else' block is executed, where the first name data is escaped before it is assigned to $first_name variable.
The elseif Statement
Sometimes, when the initial 'if' condition returns false, you may need an additional condition to check other possibilities. If we go back to our course requirement analogy, if the student had not taken the pre-requisite course to be able to take an upper-level course, there might be other ways to meet the pre-req for the uppor-level course other than taking the lower-level course. Thus, additional conditional(s) may need to be checked with 'elseif' conditional, i.e.,
if(prerequisite is met) {
take the course;
} elseif(passed a test) {
take the course
} else{
cannot take the course.
}
Note that the 'else' conditional needs to come after all 'elseif' conditionals. The 'else' conditional statement(s) is executed only when the if
and all elseif
conditionals are not met (FALSE).
Below is an example,
if (ini_get('magic_quotes_gpc')) {
$first_name = $_POST['first_name'];
}elseif(!ini_get('magic_quotes_gpc')){
$first_name = addslashes($_POST['first_name']);
}else{
echo "The server's magic quotes setting could not be read";
}
In the example above, if the magic quotes setting is enabled at the server, then the input data for the first name is assigned to $first_name without escaping the quotation marks. If the magic quotes setting is disabled, then the elseif statement conditional is checked to see if the magic quotes setting is not enabled. If this conditional is met, which means the magic quotes setting at the server is disabled, then input data for the first name is escaped and then assigned to $first_name variable. If the elseif conditional is not met either, which means that the magic quotes is enabled but the ifconditional somehow could not recognize this, then that means there is a problem with reading the
magic quotessetting because the enabled status of the magic quotes setting at the server is already checked with the
ifconditional expression and it returned false. In this case, we catch the error with the
elseconditional, where we display an error message.
Other Comparison and Logical Operators
There are many comparison operators that you can use with the conditional expressions in the if...elseif...else constructs. These are covered in unit one. Below some of them are listed again,
| Comparison | Returns TRUE If |
|---|---|
| x = = y | x equal to y |
| x != y | x is not equal to y |
| x < y | x is less than y |
| x < = y | x is less than or equal to y |
| x > y | x is greater y |
| x > = y | x is greater than or equal to y |
There are also some logical operators you can use with the conditionals when comparing two sets of comparison operations. These logical operators are also covered in unit 1, but some of them are listed below,
| Logical Operator | Usage |
|---|---|
| AND (&&) | ((3 < 4) && (4 > 3)) --> True if both comparison return true |
| OR (||) | ((3 < 4) || (4 > 3)) --> True if one of the comparisons returns true |
| NOT (!) | (!3 < 4) --> Take the opposite of the comparison. Truns true if 3 is greater than 4. |
Input Validation
The data submitted by the user needs to be validated in order to make sure that it is in the format of the expected data. If it is not, then the data may be malicious , should not be processed, and an error message should be displayed. We have seen the pattern attribute of input fields that may be used to validate the data on the client-side before the data is sent to the server. You may also use javascript to validate the data on the client-side. In this unit; however, we will take a look at how we ccan validate the data after it is submitted to the server.
There are regular expressions that may be used to validate the data on the server-side. Regular Expressions are the topic of a future unit. In addition to regular expressions, there are a few functions that you may utilize to validate the data on the server-side. The ones that we will take a look at are: empty(), isset(), and filter_var().
isset() and empty() functions
isset($data) function returns TRUE if $data has a value other than NULL/UNDEFINED. We will use isset($data) to validate input coming from checkboxes, pull-down menus, scroll-down lists, and radio buttons. If the user does not select an option on a pull down menu, checkbox, radio button, and scroll down list, then the data received for these form elements in the handling PHP file will be undefined or NULL. If the user make a selection on these form fields before submitting the form, then whatever data is assigned for the value attribute of the selected checkbox, radio button, pull down menu, or scroll down list will be received in the handling PHP file.
For example, if the user did not make any selection there was no default selected option on a pull-down menu named 'selected_option', and the user submitted the form, the following if-else statement in the form handling PHP file will execute the statement for the else block, which is "echo 'You forgot the select an option, please go back and make a selection';". If the user made a selection or if there was a default selected option on this pull-down menu, then the data set on the value attribute of the selected option in the pull down menu will be printed as a result of "echo $_POST['selected_option'];" statement.
if (isset($_POST['selected_option'])) {
echo $_POST['selected_option'];
}else {
echo 'You forgot the select an option, please go back and make a selection';
}
However, isset($data) function is not used to validate data coming from textfield, textarea, email, url, search, color, date, time, number, progress, and range type of input fields. The reason for this is that isset($data) will return TRUE even for white spaces, 0, and FALSE values. Remember that if the user does not type in any data in a textfield (email, url, search, color, date, datetime, time, progress, range, textfield are all included) or text area, a white space would be sent to the handling PHP document. Therefore, isset($data) on a textfield or textarea will not be able to differentiate whether the user typed in a data in this field or not.
empty($data) function instead of isset($data) is used to validate the existence of data submitted by a textfield or textarea. empty($data) function will return TRUE for white space(s), NULL, or 0/false. empty($data) function returns FALSE for any other value.
For example, the following if-else conditional validates the data received through the form field named 'first_name', which is a textfield in 'registration.inc.php' file. If a data other than white space, NULL, empty string, 0, or FALSE is typed into this textfield by the user, then empty($_POST['first_name']) will return FALSE, and there is a NOT operator at the beginning of the empty() function in the 'if' conditional, which takes the opposite of FALSE, which is TRUE. Therefore, the 'if' conditional, in this case, returns TRUE, and hence, 'echo $_POST['first_name'];' statement is executed.
If, on the other hand, the user did not type in any data in this text input field named 'first_name' before submitting the form, and if there was no value attribute set on this text field, then empty($_POST['first_name']) function will return TRUE, and the opposite of TRUE is FALSE; therefore, the echo statement for the if condition will not executed, instead the statement for the else condition will be executed, which is echo 'You forgot to enter your first name, please go back and type in your first name in the first name field';
if (!empty($_POST['first_name'])) {
echo $_POST['first_name'];
} else {
echo 'You forgot to enter your first name, please go back and type in your first name in the first name field';
}
filter_var($data, FILTER_VALIDATE_XXX)
This function filters the data based on the filter. If the function cannot filter the data, it returns FALSE. The data is provided as the first parameter and the filter provided as the second parameter. There are many possible filters that you may use, but the one tha twe will use in this class are: FILTER_VALIDATE_EMAIL, FILTER_VALIDATE_URL, FILTER_VALIDATE_INT, FILTER_VALIDATE_FLOAT, FILTER_VALIDATE_BOOLEAN, FILTER_VALIDATE_IP, and FILTER_VALIDATE_MAC. As you see, there is no filter for string data, but instead of using filter_var() function to validate string data types, you may use is_string($data) function.
In the following example, 'This is a valid email address' message will be printed because of the fact that 'my_email@yahoo.com' is a valid email address, and therefore filter_var($email, FILTER_VALIDATE_EMAIL) function will return TRUE.
$email = 'my_email@yahoo.com';
if(filter_var($email, FILTER_VALIDATE_EMAIL)) {
echo "This is a valid email address";
}
Errors after Submission of the Form
If any error occurs in your script, you will not be able to see those errors unless "display_errors" setting is enabled at the server. Generally, this setting is not enabled at the server because the server administrators do not want the visitors of the site see any error messages in the web browser. You can turn them on temporarily for your script. The command you need to use to turn them on is ini_set(). We also need to set the type of error and warning messages to be displayed, which will be all error and warning messages using error_reporting() function as illustrated below.
ini_set('display_errors','1');
error_reporting(E_ALL);
One issue with the script above is that we can not turn the display errors settings on within the same file where we are trying the catch the errors. We need to turn the display error setting on and set the error reporting level on a separate file where we will need to include the file that we are trying to find errors in using include() or require() function.
<?php
ini_set('display_errors','1');
error_reporting(E_ALL);
include('registration_handle.inc.php');
?>
The script above will display the errors and warning within registration_handle.inc.php
file. The file with the script above and registration_handle.inc.php
files need to be within the same folder. In addition, if the registration_handle.inc.php is the form handling document, we need to, temporarily, set the action attribute of the form to the file where we have the script above. After fixing all the errors within the registration_handle.inc.php file, we can set the action attribute of the form back to registration_handle.inc.php
isset($data) function returns TRUE if $data has a value other than NULL/UNDEFINED. We will use isset($data) to validate input coming from checkboxes, pull-down menus, scroll-down lists, and radio buttons. If the user does not select an option on a pull down menu, checkbox, radio button, and scroll down list, then the data received for these form elements in the handling PHP file will be undefined or NULL. If the user make a selection on these form fields before submitting the form, then whatever data is assigned for the value attribute of the selected checkbox, radio button, pull down menu, or scroll down list will be received in the handling PHP file.
For example, if the user did not make any selection there was no default selected option on a pull-down menu named 'selected_option', and the user submitted the form, the following if-else statement in the form handling PHP file will execute the statement for the else block, which is "echo 'You forgot the select an option, please go back and make a selection';". If the user made a selection or if there was a default selected option on this pull-down menu, then the data set on the value attribute of the selected option in the pull down menu will be printed as a result of "echo $_POST['selected_option'];" statement.
if (isset($_POST['selected_option'])) {
echo $_POST['selected_option'];
}else {
echo 'You forgot the select an option, please go back and make a selection';
}
However, isset($data) function is not used to validate data coming from textfield, textarea, email, url, search, color, date, time, number, progress, and range type of input fields. The reason for this is that isset($data) will return TRUE even for white spaces, 0, and FALSE values. Remember that if the user does not type in any data in a textfield (email, url, search, color, date, datetime, time, progress, range, textfield are all included) or text area, a white space would be sent to the handling PHP document. Therefore, isset($data) on a textfield or textarea will not be able to differentiate whether the user typed in a data in this field or not.
empty($data) function instead of isset($data) is used to validate the existence of data submitted by a textfield or textarea. empty($data) function will return TRUE for white space(s), NULL, or 0/false. empty($data) function returns FALSE for any other value.
For example, the following if-else conditional validates the data received through the form field named 'first_name', which is a textfield in 'registration.inc.php' file. If a data other than white space, NULL, empty string, 0, or FALSE is typed into this textfield by the user, then empty($_POST['first_name']) will return FALSE, and there is a NOT operator at the beginning of the empty() function in the 'if' conditional, which takes the opposite of FALSE, which is TRUE. Therefore, the 'if' conditional, in this case, returns TRUE, and hence, 'echo $_POST['first_name'];' statement is executed.
If, on the other hand, the user did not type in any data in this text input field named 'first_name' before submitting the form, and if there was no value attribute set on this text field, then empty($_POST['first_name']) function will return TRUE, and the opposite of TRUE is FALSE; therefore, the echo statement for the if condition will not executed, instead the statement for the else condition will be executed, which is echo 'You forgot to enter your first name, please go back and type in your first name in the first name field';
if (!empty($_POST['first_name'])) {
echo $_POST['first_name'];
} else {
echo 'You forgot to enter your first name, please go back and type in your first name in the first name field';
}
filter_var($data, FILTER_VALIDATE_XXX)
This function filters the data based on the filter. If the function cannot filter the data, it returns FALSE. The data is provided as the first parameter and the filter provided as the second parameter. There are many possible filters that you may use, but the one tha twe will use in this class are: FILTER_VALIDATE_EMAIL, FILTER_VALIDATE_URL, FILTER_VALIDATE_INT, FILTER_VALIDATE_FLOAT, FILTER_VALIDATE_BOOLEAN, FILTER_VALIDATE_IP, and FILTER_VALIDATE_MAC. As you see, there is no filter for string data, but instead of using filter_var() function to validate string data types, you may use is_string($data) function.
In the following example, 'This is a valid email address' message will be printed because of the fact that 'my_email@yahoo.com' is a valid email address, and therefore filter_var($email, FILTER_VALIDATE_EMAIL) function will return TRUE.
$email = 'my_email@yahoo.com';
if(filter_var($email, FILTER_VALIDATE_EMAIL)) {
echo "This is a valid email address";
}
Errors after Submission of the Form
If any error occurs in your script, you will not be able to see those errors unless "display_errors" setting is enabled at the server. Generally, this setting is not enabled at the server because the server administrators do not want the visitors of the site see any error messages in the web browser. You can turn them on temporarily for your script. The command you need to use to turn them on is ini_set(). We also need to set the type of error and warning messages to be displayed, which will be all error and warning messages using error_reporting() function as illustrated below.
ini_set('display_errors','1');
error_reporting(E_ALL);
One issue with the script above is that we can not turn the display errors settings on within the same file where we are trying the catch the errors. We need to turn the display error setting on and set the error reporting level on a separate file where we will need to include the file that we are trying to find errors in using include() or require() function.
<?php
ini_set('display_errors','1');
error_reporting(E_ALL);
include('registration_handle.inc.php');
?>
The script above will display the errors and warning within registration_handle.inc.php
file. The file with the script above and registration_handle.inc.php
files need to be within the same folder. In addition, if the registration_handle.inc.php is the form handling document, we need to, temporarily, set the action attribute of the form to the file where we have the script above. After fixing all the errors within the registration_handle.inc.php file, we can set the action attribute of the form back to registration_handle.inc.php
This function filters the data based on the filter. If the function cannot filter the data, it returns FALSE. The data is provided as the first parameter and the filter provided as the second parameter. There are many possible filters that you may use, but the one tha twe will use in this class are: FILTER_VALIDATE_EMAIL, FILTER_VALIDATE_URL, FILTER_VALIDATE_INT, FILTER_VALIDATE_FLOAT, FILTER_VALIDATE_BOOLEAN, FILTER_VALIDATE_IP, and FILTER_VALIDATE_MAC. As you see, there is no filter for string data, but instead of using filter_var() function to validate string data types, you may use is_string($data) function.
In the following example, 'This is a valid email address' message will be printed because of the fact that 'my_email@yahoo.com' is a valid email address, and therefore filter_var($email, FILTER_VALIDATE_EMAIL) function will return TRUE.
$email = 'my_email@yahoo.com';
if(filter_var($email, FILTER_VALIDATE_EMAIL)) {
echo "This is a valid email address";
}
Errors after Submission of the Form
If any error occurs in your script, you will not be able to see those errors unless "display_errors" setting is enabled at the server. Generally, this setting is not enabled at the server because the server administrators do not want the visitors of the site see any error messages in the web browser. You can turn them on temporarily for your script. The command you need to use to turn them on is ini_set(). We also need to set the type of error and warning messages to be displayed, which will be all error and warning messages using error_reporting() function as illustrated below.
ini_set('display_errors','1');
error_reporting(E_ALL);
One issue with the script above is that we can not turn the display errors settings on within the same file where we are trying the catch the errors. We need to turn the display error setting on and set the error reporting level on a separate file where we will need to include the file that we are trying to find errors in using include() or require() function.
<?php
ini_set('display_errors','1');
error_reporting(E_ALL);
include('registration_handle.inc.php');
?>
The script above will display the errors and warning within registration_handle.inc.php
file. The file with the script above and registration_handle.inc.php
files need to be within the same folder. In addition, if the registration_handle.inc.php is the form handling document, we need to, temporarily, set the action attribute of the form to the file where we have the script above. After fixing all the errors within the registration_handle.inc.php file, we can set the action attribute of the form back to registration_handle.inc.php