Introduction
Most if not all the websites today have to interact with their users one way or another. Users’ interactions give rise to dynamic web pages, the contents of which change based on who the users are (credentials), what the users are (roles), and what the users ask (functions). Unlike static web pages whose contents hardly change and thus can be crafted at design time, the content of dynamic web pages are driven by users’ interactions and thus can only be put together at run time using server-side scripting.
One of the most common user’s interaction with a dynamic website involves the user sending data to the server via a web form in a browser. From a developer’s perspective, the whole process of form handling can be divided into two parts — the front end and the back end.
- On the front end, a browser displays an HTML crafted web form consisting of one or more form widgets — text fields, text areas, drop-down lists, checkboxes, radio buttons, reset button, submit buttons, etc. — where users can enter and submit data to a server-side script on the back end. However, before any data can be sent over to the back end, they have to pass the necessary client-side validations conducted by either the HTML form validations and/or JavaScript on the front end.
- On the back end, the receiving server-side script must first filter, i.e., sanitize and/or validate, all incoming form data in accordance with the business rules of your application before the data can be accepted for further processing. To learn about filtering in PHP, attend my other lesson on PHP Filters.
In this tutorial, you will embark on a hands-on learning journey to design and implement server-side solutions in receiving, filtering, and processing form data on the back end using PHP. (You should have prior knowledge on how to create a web form on the front end before proceeding with this tutorial, if not, make a detour to Formidable Forms with HTML first.
Setting the Scene
On the document root of your local web server, create a directory called, say, testsite. In it, create a PHP file called, say, form.php which displays a web form in a browser when it is first launched via the URL http://localhost/testsite/form.php. A user can then furnish and submit data via the various form widgets on the web form. On submission, the form data will be posted back to itself, i.e. form.php, for filtering and processing on the back end. With postback (where a web form is posted back to the same URL of the file containing it), when any validations fail, the appropriate error messages can be displayed alongside the original web form to facilitate the re-entry of data and re-submission of form by the user, thus avoiding unnecessary redirection. Once the data are sanitized and/or validated successfully in accordance with the business rules of the application, form.php will simply display all the form data. This whole process is best illustrated with a flowchart as shown in Figure 1.
Figure 1: Flowchart of Form Handling on Back End
The web form inside form.php will consist of nine fields (Name
, Password
, Gender
, Residential Status
, About Me
, Email
, Web Link
, Hobbies
and Portrait
), a Reset
button and a Submit
button. For the sake of learning, let’s assume the business rules governing data filtering (sanitization and validation) for the respective fields as shown in Table 1:
Table 1: Rules for Sanitization and Validation Field | Form Widget | Sanitization Rule | Validation Rule |
Name | <input type="text" name="username"> | All HTML tags are forbidden. | Value is required. |
Password | <input type="password" name="userpassword"> | Nil. | Value is required and must be eight or more alphanumerics. |
Gender | <input type="radio" name="gender"> | Nil. | Value is required and must be one of them from citizen , pr , or foreigner . |
Residential Status | <select name="resstatus"> | Nil. | Value is required and must be eight or more alphanumerics. |
About Me | <textarea name="aboutme"> | All special characters must be converted to HTML entities. e.g. < to < . | Nil. |
Email | <input type="text" name="useremail"> | Nil. | Value is required and must be a valid email address. |
Web Link | <input type="text" name="weblink"> | Nil. | Value is optional but must be a valid URL if provided. |
Hobbies | <input type="checkbox" name="hobbies[]"> | Nil. | Value is optional but must be one or more of them from Coding , Reading , Swimming , and Others , if provided. |
Portrait | <input type="file" name="portrait"> | Nil. | Value is optional but must be of image type jpg , or jpeg , and not larger than 200 KB, if provided. |
Before you set off, catch a glimpse of the fruits that you are going to harvest at the end of the learning journey as animated in Figure 2.
Figure 2: Complete Form Handling on Back End
Getting Your Feet Wet
To start with, place the following HTML code inside form.php:
<!-- Import external PHP script here -->
<!DOCTYPE html>
<html>
<head>
<title>Form Handling with PHP</title>
</head>
<body>
<header>
<h1>Form Handling with PHP</h1>
</header>
<!--
</body>
</html>
For the sake of clarity, the main PHP script will be written in a separate PHP file called, say, include.php and be imported to form.php. To do this, create the PHP file include.php alongside form.php in the same directory. In the area marked by <!-- Import external PHP script here -->
comment inside form.php, add the following code to import include.php into form.php:
<?php include "./include.php"; ?>
You have gotten your feet wet, ready to dive in?
Diving In…
In the area marked by <!-- Add form, reset, and submit buttons -->
comment inside form.php, add the following code to define a web form with a Reset
button and a Submit
button:
<form method="post"">
<!--
<p>
<input type="reset" value="Reset">
<input type="submit" name="usersubmit" value="Submit">
</p>
</form>
In the absence of the action
attribute, on clicking the Submit
button, this form will be submitted to itself, i.e., form.php on the back end, using the POST
method. To read up on communication between the browser and the web server, visit Conversation over HTTP.
From here on, your journey is going to become more exhilarating, so hold your breath and…
Name Field
In the area marked by <!-- Add form widgets here -->
comment inside form.php, add the following code to define a text widget for the Name
field as follows:
<p>Name:<br><input type="text" name="username"></p>
On form submission, the value entered into this text widget will get sent over to the back end. How does the server-side script handle it? Pay attention from this point onward…
include.php
Inside include.php, create two associative arrays called $messages
and $postback
respectively as follows:
<?php
$messages = [
"username" => "*"
];
$postback = [
"username" => ""
];
?>
- The
$message
stores an associative array of messages in the form of form_widget_name=>message
pairs, to be displayed alongside their corresponding form widgets on the front end, telling the user if an entry is required (with an *
sign) , optional (with an empty string), or it fails the server-side validation. For now, it contains only one element, i.e. "username" => "*"
, which is to display an *
beside the Name
text widget to indicate that it is a required field on the front end. You will write the PHP code to implement this in a while. - The
$postback
stores all form data as an associative array of values in the form of form_widget_name=>value
pairs, to be used to auto-fill their corresponding form widgets when the same page is sent back to the user for re-entry owing to any validation failures on the server side. For now, it contains only one element, i.e. "username" => ""
, which is to display an empty value in the Name
text widget on the front end. You will write the PHP code to implement this in a while.
form.php
When form.php is first loaded, it should display an *
beside the Name
text widget with an empty value. You have already prepared these initial values in $messages
and $postback
arrays respectively inside include.php, it is a matter of echoing them out using inline PHP as follows:
- To display the initial
*
sign for required field or subsequent message for failing a validation beside the Name
text widget, echo the value of username
key in $messages
array inside a <span>
element alongside the Name
text widget like this:
<span style="color: red"><?php echo $messages["username"]; ?><span>
Using a <span>
allows its content to be styled using CSS, such as rendering the message in red in this example.
- To display the initial empty value or subsequent postback value in the
Name
text widget, echo the value of username
in $postback
array to the value
attribute of the text widget like this:
value="<?php echo $postback["username"]; ?>"
Putting them together, the initial HTML code for...
<p>Name:<br><input type="text" name="username"</p>
...becomes...
<p>Name:<br><input type="text" name="username"
value="<?php echo $postback["username"]; ?>">
<span style="color: red"><?php echo $messages["username"]; ?><span></p>
...and your form.php should now contain the following code:
<?php include "./include.php"; ?>
<!DOCTYPE html>
<html>
<head>
<title>Form Handling with PHP</title>
</head>
<body>
<header>
<h1>Form Handling with PHP</h1>
</header>
<form method="post"">
<p>Name:<br><input type="text" name="username"
value="<?php echo $postback["username"]; ?>">
<span style="color: red"><?php echo $messages["username"]; ?><span></p>
<p>
<input type="reset" value="Reset">
<input type="submit" name="usersubmit" value="Submit">
</p>
</form>
</body>
</html>
Launching form.php in the browser and you should be able to achieve this animated output as shown in Figure 3:
Figure 3: An Uneventful Form
As it is now, the same page simply re-appears upon clicking the Submit
button. It’s time to get the server-side script to work harder!
Empowering include.php
To begin with, the PHP script must be able to differentiate if a request is a new one or a postback originated from a form submission. You can ascertain this by checking out the request method element of the superglobal variable $_SERVER
. Since form.php is using POST
method, you can check if a request is a postback with the following code snippet:
if($_SERVER["REQUEST_METHOD"] == "POST"){
}
If the outcome of the condition is false
, it will skip the form data processing code and simply display a brand new form. If the outcome of the condition is true
, i.e., it is a postback, then you will need to write code to implement the following steps for handling the form data:
Step 1
To sanitize form data that requires sanitization in accordance with the business rules of the application.
Step 2
To validate that the form data or the sanitized data (if sanitization is required) is in accordance with the business rules of the application. If a piece of data fails its validation check, update the value of the key corresponding to this data in the $messages
array from the default *
to an appropriate message.
Step 3
Generally, if the $messages
array contains any values other than the default *
or empty string
, it is a sign that some of the data fail their validation rules, it then returns to form.php and displays the respective $message
values alongside their corresponding form widgets. If all the values in the $messages
array are either *
or empty string
s, it is a sign that all data pass their validation rules, it then simply echoes the data. In a real application, these data may be saved into a database or be used in subsequent redirection to other pages in accordance with application requirements.
Let’s implement these steps for the data submitted via the Name
text widget in accordance to the rules stipulated for it in Table 1.
All the form data submitted via post
method are stored in the superglobal $_POST
associative array where the data submitted by each form widget can be accessed using the value of that form widget name
attribute as the key. Since the name
attribute of the Name
text widget is given the value of username
, you can access its data submitted to the server-side script with this code snippet:
$username = $_POST["username"];
Step 1
Sanitize the value of $username
using FILTER_SANITIZE_STRING
filter to remove any HTML tags, and then assign the sanitized value to $postback["username"]
. The code to implement this step is shown as follows:
$postback["username"] = filter_var($username, FILTER_SANITIZE_STRING);
Step 2
Validate if the value of $postback["username"]
is empty using the PHP functions of trim()
and empty()
. If it is empty, update $messages["username"]
from the default value of *
to a value that reads Name is required
. The code to implement this step is shown as follows:
$postback["username"] = trim($postback["username"]);
if(empty($postback["username"])){
$messages["username"] = "Name is required";
}
Step 3
If all the keys in $messages
associative array retain their default values, i.e., either *
or empty string
, it is a sign that all the data pass their validations. So far, there is only one element in $messages
array, i.e., $messages["username"]
, as long as the count of *
value in $messages
is 1
, it indicates that the value submitted via the Name
text widget passes its validation, it then returns to form.php and displays the value of $postback["username"]
. On the contrary, if the count of *
value in $messages
is not 1
, it indicates that the value submitted via the Name
text widget fails its validation, it then returns to form.php and displays the initial web form but with the added message that reads Name is required
beside the Name
text widget. The code to implement this step is shown as follows:
$array = array_count_values($messages);
if(array_key_exists("*", $array) && $array["*"] == 1){
echo "Name: ", $postback["username"], "<br>";
exit;
}
Putting together all the pieces that you have picked up so far, you get an empowered include.php as shown below:
<?php
$messages = [
"username" => "*"
];
$postback = [
"username" => ""
];
if($_SERVER["REQUEST_METHOD"] === "POST"){
$username = $_POST["username"];
$postback["username"] = filter_var($username, FILTER_SANITIZE_STRING);
$postback["username"] = trim($postback["username"]);
if(empty($postback["username"])){
$messages["username"] = "Name is required";
}
$array = array_count_values($messages);
if(array_key_exists("*", $array) && $array["*"] == 1){
echo "Name: ", $postback["username"], "<br>";
exit;
}
}
?>
You have completed the form handling on Name
field. You may taste the fruits of your labour by checking out form.php in your browser or enjoy an animated clip as shown in Figure 4:
Figure 4: Name Field
In the preceding session, you have learned the fundamentals of form handling on the back end through an exercise using the Name
text widget. You can now confidently apply these fundamentals in designing and implementing form handling solutions on the back end for the other form widgets.
Password Field
Continue to implement form handling on Password
password widget in accordance to the rules stipulated for it in Table 1.
form.php
Immediately below the Name
text widget inside form.php, add the following code to define a password widget for the Password
field as follows:
<p>Password:<br><input type="password" name="userpassword"
value="<?php echo $postback["userpassword"]; ?>">
<span style="color: red"><?php echo $messages["userpassword"]; ?><span></p>
include.php
Inside include.php, add "userpassword" => "*"
and "userpassword" => ""
to $messages
and $postback
respectively as shown:
$messages = [
"username" => "*",
"userpassword" => "*"
];
$postback = [
"username" => "",
"userpassword" => ""
];
Since the name
attribute of the Password
password widget is given the value of userpassword
, you can access its data submitted to the server-side script with this code snippet:
$userpassword = $_POST["userpassword"];
Step 1
Sanitization is not required for Password
field according to Table 1.
Step 2
Validate that the value of $userpassword
has eight or more alphanumerics. If the validation passes, assign the value of $userpassword
to $postback["userpassword"]
, otherwise, update $messages["userpassword"]
from the default value of *
to a value that reads Password must be eight or more aplphanumerics
. The code to implement this step is shown as follows:
$options = array(
'options' => array(
'regexp' => '/^[A-Za-z0-9]{8,}$/'
)
);
if(filter_var($userpassword, FILTER_VALIDATE_REGEXP, $options)){
$postback["userpassword"] = $userpassword;
} else {
$messages["userpassword"] = "Password must have eight or more aplphanumerics";
}
Step 3
Change the count of *
value in $messages
to 2
and include the code to echo the value of $postback["userpassword"]
as shown:
$array = array_count_values($messages);
if(array_key_exists("*", $array) && $array["*"] == 2){
echo "Name: ", $postback["username"], "<br>";
echo "Password: ", $postback["userpassword"], "<br>";
exit;
}
Putting together all the pieces that you have picked up so far and you get an empowered include.php as shown below:
<?php
$messages = [
"username" => "*",
"userpassword" => "*"
];
$postback = [
"username" => "",
"userpassword" => ""
];
if($_SERVER["REQUEST_METHOD"] === "POST"){
$username = $_POST["username"];
$postback["username"] = filter_var($username, FILTER_SANITIZE_STRING);
$postback["username"] = trim($postback["username"]);
if(empty($postback["username"])){
$messages["username"] = "Name is required";
}
$userpassword = $_POST["userpassword"];
$options = array(
'options' => array(
'regexp' => '/^[A-Za-z0-9]{8,}$/'
)
);
if(filter_var($userpassword, FILTER_VALIDATE_REGEXP, $options)){
$postback["userpassword"] = $userpassword;
} else {
$messages["userpassword"] = "Password must have eight or more aplphanumerics";
}
$array = array_count_values($messages);
if(array_key_exists("*", $array) && $array["*"] == 2){
echo "Name: ", $postback["username"], "<br>";
echo "Password: ", $postback["userpassword"], "<br>";
exit;
}
}
?>
You have completed the form handling on the Password
field. You may taste the fruits of your labour by checking out form.php in your browser or enjoy an animated clip as shown in Figure 5:
Figure 5: Password Field
Gender Radio Group
Continue to implement form handling on Gender
radio group in accordance to the rules stipulated for it in Table 1.
form.php
Immediately below the Password
password widget inside form.php, add the following code to define two radio buttons for Gender
options as follows:
<fieldset>
<legend>Gender</legend>
Male: <input type="radio" name="gender" value="male"
<?php echo $postback["gender"] === "male" ? "checked" : ""; ?>>
Female: <input type="radio" name="gender" value="female"
<?php echo $postback["gender"] === "female" ? "checked" : ""; ?>>
<span style="color: red"><?php echo $messages["gender"]; ?>
</fieldset>
include.php
Inside include.php, add "gender" => "*"
and "gender" => "male"
to $messages
and $postback
respectively as shown:
$messages = [
"username" => "*",
"userpassword" => "*",
"gender" => "*"
];
$postback = [
"username" => "",
"userpassword" => "",
"gender" => "male"
];
The "gender" => "male"
element of $postback
will make sure that the “Male
” option of Gender
radio group is selected by default.
Since the name
attribute of the Gender
radio group is given the value of gender
, you can access the selected option submitted to the server-side script with this code snippet:
$gender = $_POST["gender"];
Step 1
Sanitization is not required for the Gender
radio group according to Table 1.
Step 2
Validate that the value of $gender
is either male
or female
. If the validation passes, assign the value of $gender
to $postback["gender"]
, otherwise, update $messages["gender"]
from the default value of *
to a value that reads Gender is required
. The code to implement this step is shown as follows:
if(in_array($gender, ["male", "female"], TRUE)){
$postback["gender"] = $gender;
} else {
$messages["gender"] = "Gender is required";
}
Step 3
Change the count of *
value in $messages
to 3
and include the code to echo the value of $postback["gender"]
as shown:
$array = array_count_values($messages);
if(array_key_exists("*", $array) && $array["*"] == 3){
echo "Name: ", $postback["username"], "<br>";
echo "Password: ", $postback["userpassword"], "<br>";
echo "Gender: ", $postback["gender"], "<br>";
exit;
}
You have completed the form handling on the Gender
radio group. You may taste the fruits of your labour by checking out form.php in your browser or enjoy an animated clip as shown in Figure 6:
Figure 6: Gender Radio Group
Residential Status Drop-down List
Continue to implement form handling on Residential Status
drop-down List in accordance to the rules stipulated for it in Table 1.
form.php
Immediately below the Gender
radio group inside form.php, add the following code to define a drop-down list for Residential Status
as follows:
<p>
Residential Status:<br>
<select name="resstatus">
<option value=""></option>
<option value="citizen" <?php echo $postback["resstatus"] === "citizen" ?
"selected" : ""; ?>>Citizen</option>
<option value="pr" <?php echo $postback["resstatus"] === "pr" ?
"selected" : ""; ?>>Permanent Resident</option>
<option value="foreigner" <?php echo $postback["resstatus"] === "foreigner" ?
"selected" : ""; ?>>Foreigner</option>
</select>
<span style="color: red"><?php echo $messages["resstatus"]; ?>
</p>
include.php
Inside include.php, add "resstatus" => "*"
and "resstatus" => ""
to $messages
and $postback
respectively as shown:
$messages = [
"username" => "*",
"userpassword" => "*",
"gender" => "*",
"resstatus" => "*"
];
$postback = [
"username" => "",
"userpassword" => "",
"gender" => "male",
"resstatus" => ""
];
Since the name
attribute of the Residential Status
drop-down List is given the value of resstatus
, you can access the selected option submitted to the server-side script with this code snippet:
$resstatus = $_POST["resstatus"];
Step 1
Sanitization is not required for the Residential Status
drop-down list according to Table 1.
Step 2
Validate that the value of $resstatus
is from one of these: citizen
, pr
, or foreigner
. If the validation passes, assign the value of $resstatus
to $postback["resstatus"]
, otherwise, update $messages["resstatus"]
from the default value of *
to a value that reads Residential Status is required
. The code to implement this step is shown as follows:
if(in_array($resstatus, ["citizen", "pr" , "foreigner"], TRUE)){
$postback["resstatus"] = $resstatus;
} else {
$messages["resstatus"] = "Residential Status is required";
}
Step 3
Change the count of *
value in $messages
to 4
and include the code to echo the value of $postback["resstatus"]
as shown:
$array = array_count_values($messages);
if(array_key_exists("*", $array) && $array["*"] == 4){
echo "Name: ", $postback["username"], "<br>";
echo "Password: ", $postback["userpassword"], "<br>";
echo "Gender: ", $postback["gender"], "<br>";
echo "Residential Status: ", $postback["resstatus"], "<br>";
exit;
}
You have completed the form handling on the Residential Status
drop-down list. You may taste the fruits of your labour by checking out form.php in your browser or enjoy an animated clip as shown in Figure 7:
Figure 7: Residential Status Drop-down List
About Me Text Box
Continue to implement form handling on About Me
text box in accordance with the rules stipulated for it in Table 1.
form.php
Immediately below the Residential Status
drop-down list inside form.php, add the following code to define a multi-line text box for About Me
as follows:
<p>About Me:<br><textarea name="aboutme" rows="10" cols="30">
<?php echo $postback["aboutme"]; ?></textarea></p>
Notice the absence of inline PHP code for $message
included for the preceding widgets. Since the About Me
text box does not require any validation, there is no need to display *
or any message for failing validation.
include.php
Inside include.php, add "aboutme" => ""
to $postback
.
Since the name
attribute of the About Me
text box is given the value of aboutme
, you can access its data submitted to the server-side script with this code snippet:
$aboutme = $_POST["aboutme"];
Step 1
Sanitize the value of $aboutme
using FILTER_SANITIZE_FULL_SPECIAL_CHARS
filter to convert special characters, i.e. &
, "
, '
, <
, and >
, to their corresponding HTML entities, and then assign the sanitized value to $postback["aboutme"]
. The code to implement this step is shown as follows:
$postback["aboutme"] = filter_var($aboutme, FILTER_SANITIZE_FULL_SPECIAL_CHARS);
Step 2
Validation is not required for the About Me
text box.
Step 3
Include the code to echo the value of $postback["aboutme"]
as shown:
$array = array_count_values($messages);
if(array_key_exists("*", $array) && $array["*"] == 4){
echo "Name: ", $postback["username"], "<br>";
echo "Password: ", $postback["userpassword"], "<br>";
echo "Gender: ", $postback["gender"], "<br>";
echo "Residential Status: ", $postback["resstatus"], "<br>";
echo "About Me: ", $postback["aboutme"], "<br>";
exit;
}
You have completed the form handling on the About Me
text box. You may taste the fruits of your labour by checking out form.php in your browser or enjoy an animated clip as shown in Figure 8:
Figure 8: About Me Text Box
Email Field
Continue to implement form handling on Email
text widget in accordance to the rules stipulated for it in Table 1.
form.php
Immediately below the About Me
text box inside form.php, add the following code to define a text widget for the Email
field as follows:
<p>Email:<br><input type="text" name="useremail"
value="<?php echo $postback["useremail"]; ?>">
<span style="color: red"><?php echo $messages["useremail"]; ?><span></p>
include.php
Inside include.php, add "useremail" => "*"
and "useremail" => ""
to $messages
and $postback
respectively.
Since the name
attribute of the Email
text widget is given the value of useremail
, you can access its data submitted to the server-side script with this code snippet:
$useremail = $_POST["useremail"];
Step 1
Sanitization is not required for the Email
field according to Table 1.
Step 2
Validate that the value of $useremail
is of valid email format as shown:
$useremail = trim($useremail);
if(filter_var($useremail, FILTER_VALIDATE_EMAIL)){
$postback["useremail"] = $useremail;
} else {
$messages["useremail"] = "Must be a valid email";
}
Step 3
Change the count of *
value in $messages
to 5
and include the code to echo the value of $postback["useremail"]
as shown:
$array = array_count_values($messages);
if(array_key_exists("*", $array) && $array["*"] == 5){
echo "Name: ", $postback["username"], "<br>";
echo "Password: ", $postback["userpassword"], "<br>";
echo "Gender: ", $postback["gender"], "<br>";
echo "Residential Status: ", $postback["resstatus"], "<br>";
echo "About Me: ", $postback["aboutme"], "<br>";
echo "Email: ", $postback["useremail"], "<br>";
exit;
}
You have completed the form handling on the Email
field. You may taste the fruits of your labour by checking out form.php in your browser or enjoy an animated clip as shown in Figure 9:
Figure 9: Email Field
Web Link Field
Continue to implement form handling on Web Link
text widget in accordance to the rules stipulated for it in Table 1.
form.php
Immediately below the Email
text widget inside form.php, add the following code to define a text widget for the Web Link field as follows:
<p>Web Link:<br><input type="text" name="weblink"
value="<?php echo $postback["weblink"]; ?>">
<span style="color: red"><?php echo $messages["weblink"]; ?><span></p>
include.php
Inside include.php, add "weblink" => ""
to both $messages
and $postback
respectively.
Since the name
attribute of the Web Link
text widget is given the value of weblink
, you can access its data submitted to the server-side script with this code snippet:
$weblink = $_POST["weblink"];
Step 1
Sanitization is not required for the Web Link field according to Table 1.
Step 2
Validate that the value of $weblink
is of valid URL format as shown:
if(filter_var($weblink, FILTER_VALIDATE_URL)){
$postback["weblink"] = $weblink;
} elseif (!empty($weblink)){
$messages["weblink"] = "Must be a valid URL";
}
Step 3
Add the condition to check the successful validation of $weblink
, i.e. empty($messages["weblink"])
, and then to echo the value of $postback["weblink"]
as shown:
$array = array_count_values($messages);
if(array_key_exists("*", $array) && $array["*"] == 5 && empty($messages["weblink"])){
echo "Name: ", $postback["username"], "<br>";
echo "Password: ", $postback["userpassword"], "<br>";
echo "Gender: ", $postback["gender"], "<br>";
echo "Residential Status: ", $postback["resstatus"], "<br>";
echo "About Me: ", $postback["aboutme"], "<br>";
echo "Email: ", $postback["useremail"], "<br>";
echo "Web Link: ", $postback["weblink"], "<br>";
exit;
}
You have completed the form handling on the Web Link field. You may taste the fruits of your labour by checking out form.php in your browser or enjoy an animated clip as shown in Figure 10:
Figure 10: Web Link Field
Hobbies Checkbox Group
Continue to implement form handling on Hobbies
checkbox group in accordance to the rules stipulated for it in Table 1.
So far, you have been dealing with single-value form data, with checkbox group, however, you will expect muti-value form data as the user can select multiple options from a checkbox group. To handle muti-value form data, use array.
form.php
Immediately below the Web Link
text widget inside form.php, add the following code to define a checkbox
group for the Hobbies
options as follows:
<p>Hobbies:<br>
<input type="checkbox" name="hobbies[]" value="coding"
<?php echo in_array("coding", $postback["hobbies"], TRUE) ? "checked" : ""; ?>>Coding<br>
<input type="checkbox" name="hobbies[]" value="reading"
<?php echo in_array("reading", $postback["hobbies"], TRUE) ? "checked" : ""; ?>>Reading<br>
<input type="checkbox" name="hobbies[]" value="swimming"
<?php echo in_array("swimming", $postback["hobbies"], TRUE) ? "checked" : ""; ?>>Swimming<br>
<input type="checkbox" name="hobbies[]" value="others"
<?php echo in_array("others", $postback["hobbies"], TRUE) ? "checked" : ""; ?>>Others
</p>
include.php
Inside include.php, add "hobbies" => []
to $postback
. This $postback["hobbies"]
is an sub-array that will uncheck all the checkboxes of the Hobbies
checkbox group initially and stores any values submitted from the Hobbies
checkbox group subsequently.
Since the name
attribute of each Hobbies
checkbox is given the value of hobbies[]
, you can access the checked options submitted to the server-side script with this code snippet:
$hobbies = $_POST["hobbies"];
However, the above code will get you into trouble if the user submits the form without selecting any hobbies. If such situation occurs, initialize $hobbies
to an empty array. Use the following code instead:
$hobbies = isset($_POST["hobbies"]) ? $_POST["hobbies"] : [];
Step 1
Sanitization is not required for the Hobbies
checkbox group according to Table 1.
Step 2
Validate that the values of $hobbies
, if provided, must be coding
, reading
, swimming
, and/or others
as shown:
if(array_sum(array_map(function($arg)
{return in_array($arg, ["coding", "reading", "swimming", "others"]);},
$hobbies)) == count($hobbies)){
$postback["hobbies"] = $hobbies;
}
Step 3
Include the code to echo the values of $postback["hobbies"]
as shown:
$array = array_count_values($messages);
if(array_key_exists("*", $array) && $array["*"] == 5 && empty($messages["weblink"])){
echo "Name: ", $postback["username"], "<br>";
echo "Password: ", $postback["userpassword"], "<br>";
echo "Gender: ", $postback["gender"], "<br>";
echo "Residential Status: ", $postback["resstatus"], "<br>";
echo "About Me: ", $postback["aboutme"], "<br>";
echo "Email: ", $postback["useremail"], "<br>";
echo "Web Link: ", $postback["weblink"], "<br>";
echo "Hobbies: ", join(', ', $postback["hobbies"]), "<br>";
exit;
}
You have completed the form handling on the Hobbies
checkbox group. You may taste the fruits of your labour by checking out form.php in your browser or enjoy an animated clip as shown in Figure 11:
Figure 11: Hobbies Checkbox Group
Portrait File Upload
Continue to implement form handling on Portrait
file upload widget in accordance to the rules stipulated for it in Table 1.
form.php
Immediately below the Hobbies
checkbox group inside form.php, add the following code to define a file upload widget for the Portrait
field as follows:
<p>Portrait:<br><input type="file" name="portrait"
value="<?php echo $postback["portrait"]; ?>">
<span style="color: red"><?php echo $messages["portrait"]; ?><span></p>
For the <input type="file">
widget to work, however, you have to make sure the form:
* Uses method="post"
; and
* Includes enctype
attribute with the value of multipart/form-data
to the <form>
tag. It specifies that the content must not be encoded and be transmitted as a stream.
So, modify the <form>
to this:
<form method="post" enctype="multipart/form-data">
include.php
Inside include.php, add "portrait" => ""
to both $messages
and $postback
.
Since the name
attribute of each Portrait
file upload widget is given the value of portrait
, you can access its data submitted to the server-side script with this code snippet:
$portrait = $_FILES["portrait"];
However, the above code will get you into trouble if the user submits the form without selecting any files. If such situation occurs, initialize $portrait
to an empty array. Use the following code instead:
$portrait = isset($_FILES["portrait"]) ? $_FILES["portrait"] : [];
$_FILES
is the superglobal variable that contains an associative array of file related data for any files uploaded to the current script via HTTP POST
method. (To learn more about $_FILES
, attend my other lesson on PHP Superglobals.
Step 1
Sanitization is not required for the Portrait
File Upload according to Table 1.
Step 2
Validate that the uploaded file must be of image type jpg
, or jpeg
, and not larger than 200KB, if provided:
if($portrait["error"] === UPLOAD_ERR_OK &&
(!in_array(strtolower($portrait["type"]),
["image/jpg", "image/jpeg"]) || $portrait["size"] > 200*1024)) {
$messages["portrait"] = "File type must be of jpg or jpeg and
file size must not exceed 200 KB";
} else if($portrait["error"] == UPLOAD_ERR_NO_FILE){
$postback["portrait"] = "";
} else {
$tmp_name = $portrait["tmp_name"];
$file_name = basename($portrait["name"]);
move_uploaded_file($tmp_name, $file_name);
$postback["portrait"] = "<img src='$file_name' align='top' width='100px'>";
}
Every file uploaded to the server is stored temporarily with a file name accessible via the tmp_name
key of the $_FILES
array, such as $_FILES["portrait"]["tmp_name"]
in our example. This temporary file will be deleted when the script that handles the form data ends. Therefore, if you want to keep the file beyond the script execution, you have to move it to a permanent location explicitly using the move_uploaded_file()
function as shown in the script in Step 2 above.
Step 3
Add the condition to check the successful validation of $portrait
, i.e. empty($messages["portrait"])
, and then to echo the value of $postback["portrait"]
as shown::
$array = array_count_values($messages);
if(array_key_exists("*", $array) && $array["*"] == 5 &&
empty($messages["weblink"]) && empty($messages["portrait"])){
echo "Name: ", $postback["username"], "<br>";
echo "Password: ", $postback["userpassword"], "<br>";
echo "Gender: ", $postback["gender"], "<br>";
echo "Residential Status: ", $postback["resstatus"], "<br>";
echo "About Me: ", $postback["aboutme"], "<br>";
echo "Email: ", $postback["useremail"], "<br>";
echo "Web Link: ", $postback["weblink"], "<br>";
echo "Hobbies: ", join(', ', $postback["hobbies"]), "<br>";
echo "Portrait: ", $postback["portrait"], "<br>";
exit;
}
You have completed the form handling on the Portrait
file upload. You may taste the fruits of your labour by checking out form.php in your browser or enjoy an animated clip as shown in Figure 12:
Figure 12: Portrait File Upload
Mission Accomplished
You have touched down. You have successfully completed a hands-on learning journey to design and implement server-side solutions in receiving, filtering, and processing form data on the back end using PHP. You can now enjoy the fruits of your labour as animated in Figure 2 at the beginning of this article.
The post Form Handling with PHP appeared first on Peter Leow's Blog.