Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / HTML

Form Handling with PHP

5.00/5 (5 votes)
11 Sep 2018CPOL22 min read 27.6K  
Learn to handle form in PHP

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.

  1. 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.
  2. 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

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 &#60;. 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

Figure 2: Complete Form Handling on Back End

Getting Your Feet Wet

To start with, place the following HTML code inside form.php:

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>

<!-- Add form, reset, and submit buttons -->

</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
<?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:

PHP
<form method="post"">
  <!-- Add form widgets here -->
  <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:

PHP
<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
<?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:
PHP
<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:
PHP
value="<?php echo $postback["username"]; ?>"

Putting them together, the initial HTML code for...

PHP
<p>Name:<br><input type="text" name="username"</p>

...becomes...

PHP
<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
<?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

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:

PHP
if($_SERVER["REQUEST_METHOD"] == "POST"){
  // Add form data processing code
}

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 strings, 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:

PHP
$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:

PHP
$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:

PHP
$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:

PHP
$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
<?php
$messages = [
  "username" => "*"
];

$postback = [
  "username" => ""
];

if($_SERVER["REQUEST_METHOD"] === "POST"){
  
  /* Name Field */
  
  $username = $_POST["username"];
  
  // Step 1: Remove any HTML tags from $username and assign it to $postback["username"]
  $postback["username"] = filter_var($username, FILTER_SANITIZE_STRING);
  
  // Step 2: Validate that $username is not empty
  $postback["username"] = trim($postback["username"]);
  if(empty($postback["username"])){
  $messages["username"] = "Name is required";
  }
    
  /* Step 3: Determine if validations are successful */
  $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

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:

PHP
<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:

PHP
$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:

PHP
$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:

PHP
$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:

PHP
$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
<?php
$messages = [
  "username" => "*",
  "userpassword" => "*"
];

$postback = [
  "username" => "",
  "userpassword" => ""
];

if($_SERVER["REQUEST_METHOD"] === "POST"){
  
  /* Name Field */
  
  $username = $_POST["username"];
  
  // Step 1: Remove any HTML tags from $username and assign it to $postback["username"]
  $postback["username"] = filter_var($username, FILTER_SANITIZE_STRING);
  
  // Step 2: Validate that $username is not empty
  $postback["username"] = trim($postback["username"]);
  if(empty($postback["username"])){
  $messages["username"] = "Name is required";
  }

  /* Password Field */
  
  $userpassword = $_POST["userpassword"];
  
  // Step 1: Nil
  
  // Step 2: Validate that $userpassword has 8 or more alphanumerics
  $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: Determine if validations are successful */
  $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

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:

PHP
<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:

PHP
$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:

PHP
$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:

PHP
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:

PHP
$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

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:

PHP
<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:

PHP
$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:

PHP
$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:

PHP
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:

PHP
$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

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:

PHP
<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:

PHP
$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:

PHP
$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:

PHP
$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

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:

PHP
<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:

PHP
$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:

PHP
$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:

PHP
$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

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:

PHP
<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:

PHP
$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:

PHP
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:

PHP
$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

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:

PHP
<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:

PHP
$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:

PHP
$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:

PHP
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:

PHP
$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

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:

PHP
<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:

PHP
<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:

PHP
$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:

PHP
$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:

PHP
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){ // No file is uploaded
  
  $postback["portrait"] = "";
  
} else { // Uploaded file passed the validation
  
  $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::

PHP
$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

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.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)