PHP Form Validation and Error Handling
Updated: 14-Feb-2025 / Tags: PHP Tutorials / Views: 33 - Author: George
Introduction
Hello everyone.
In this tutorial, I will demonstrate how to handle form data using PHP.
I will cover the common form elements typically used in web forms, including input fields, text-area, select drop down menus, radio buttons and check boxes.
We will sanitize and validate the submitted values to ensure that the data is clean and safe for further processing
We will display validation error messages when the values don't meet our criteria, and a success message when everything goes well.
Also this will be a sticky form, this means that in case of an error the values that the user entered in the input fields and also in the select menu, radio buttons, and check boxes will be preserved, contributing to a positive user experience.
So let's dive in.
Live Demo
I have created a live demo so you can try out the various input elements. Make some errors to see the error messages appear under the input fields. The code that we will write will replicate the exact form that we have here in the live demo.
All form fields are required.
Project's folder
In your localhost server create a project folder (you can name it anything you like). Inside the project folder create an index.php file, a form-validation.php file, and a styles.css file.
That's all the files that we need.
/--projects-folder |--index.php |--form-validation.php |--styles.css
The index.php file
The index.php file contains the HTML form that you saw in the live demo.
<form action="" method="post" enctype="">
<!-- Displaying the success message if there are no validation errors -->
<?php
if(isset($success_message)){
?>
<p class="success"><?php echo $success_message ?></p>
<?php
}
?>
<!-- First name Input field ============================================ -->
<label for="firstname">Enter your first name</label>
<input id="firstname" type="text"
name="firstname" value="<?php echo @$_POST['firstname'] ?> ">
<!-- The $_POST['firstname'] variable will preserve
the user's input in case of an error. The @ sign prevents the server
to throw a warning when a variable is not defined -->
<!-- In this code block we display an error if the first name validation fails -->
<?php
if($firstname_error){
?>
<p class="error"><?php echo $firstname_error ?></p>
<?php
}
?>
<!-- Email input field ===================================================== -->
<label for="email">Enter your email</label>
<input id="email" type="text"
name="email" value="<?php echo @$_POST["email"] ?> ">
<!-- Displaying an error if the email validation fails -->
<?php
if($email_error){
?>
<p class="error"><?php echo $email_error ?></p>
<?php
}
?>
<!-- Textarea ============================================================ -->
<label for="profile-description">Write a few words about you</label>
<textarea id="profile-description" name="profile-description">
<?php echo @$_POST['profile-description'] ?>
</textarea>
<!-- Displaying an error if the profile description validation fails -->
<?php
if($profile_description_error){
?>
<p class="error"><?php echo $profile_description_error ?></p>
<?php
}
?>
<!-- Dropdown select menu ================================================== -->
<label>Select you favorite color</label>
<select name="fav-color">
<!-- In case of an error we display the selected option -->
<?php
if(isset($_POST['fav-color']) && !empty($_POST['fav-color'])){
?>
<option value="<?php echo $_POST['fav-color'] ?>">
<?php echo ucfirst($_POST['fav-color']) ?>
</option>
<?php
}
?>
<option value="">Select a color</option>
<option value="red">Red</option>
<option value="green">Green</option>
<option value="blue">Blue</option>
<option value="black">Black</option>
</select>
<!-- Displaying an error if the favorite color validation fails -->
<?php
if($fav_color_error){
?>
<p class="error"><?php echo $fav_color_error ?></p>
<?php
}
?>
<!-- Radio buttons ================================================== -->
<div class="radio-buttons">
<label>Select Gender</label>
<!-- Checking the selected radio button in case of an error
so we do not lose the user input -->
<?php
$male_checked = null; $female_checked = null;
if(isset($_POST['gender']) && $_POST['gender'] == "male"){
$male_checked = "checked";
}else if(isset($_POST['gender']) && $_POST['gender'] == "female"){
$female_checked = "checked";
}
?>
<span>Male</span>
<input type="radio" name="gender" value="male"
<?php echo $male_checked; ?>>
<!-- The $male_checked variable has either the value 'null' or 'checked'.
If checked we preserve the user input in case of an error. -->
<span>Female</span>
<input type="radio" name="gender" value="female"
<?php echo $female_checked; ?>>
<!-- The $female_checked variable has either the value 'null' or 'checked'.
If checked we preserve the user input in case of an error. -->
<!-- Displaying error message when no gender is selected-->
<?php
if($gender_error){
?>
<p class="error"><?php echo $gender_error ?></p>
<?php
}
?>
</div>
<!-- Checkboxes ================================================== -->
<div class="checkboxes">
<label>Select the foods you like</label>
<!-- Checking the selected check boxes in case of an error
so we do not lose the user input -->
<?php
$pizza_checked = null; $spaghetti_checked = null; $broccoli_checked = null;
if(isset($_POST['fav_foods'])){
if(in_array('pizza', $_POST['fav_foods'])){
$pizza_checked = 'checked';
}
if(in_array('spaghetti', $_POST['fav_foods'])){
$spaghetti_checked = 'checked';
}
if(in_array('broccoli', $_POST['fav_foods'])){
$broccoli_checked = 'checked';
}
}
?>
<span>Pizza</span>
<!-- In order to group checkboxes together we insert in the
name attribute an array which will hold the values of the
checked checkboxes. In this case 'name=fav_foods[]' -->
<input type="checkbox" name="fav_foods[]" value="pizza"
<?php echo $pizza_checked ?>>
<!-- The $pizza_checked variable has either the value 'null' or 'checked'.
If checked we preserve the user input in case of an error. -->
<span>Spaghetti</span>
<input type="checkbox" name="fav_foods[]" value="spaghetti"
<?php echo $spaghetti_checked ?>>
<!-- The $spaghetti_checked variable has either the value 'null' or 'checked'.
If checked we preserve the user input in case of an error. -->
<span>Broccoli</span>
<input type="checkbox" name="fav_foods[]" value="broccoli"
<?php echo $broccoli_checked ?>>
<!-- The $broccoli_checked variable has either the value 'null' or 'checked'.
If checked we preserve the user input in case of an error. -->
<!-- Displaying an error if no fav food is selected -->
<?php
if($fav_food_error){
?>
<p class="error"><?php echo $fav_food_error ?></p>
<?php
}
?>
</div>
<!-- Submit button -->
<button type="submit" name="submit">Submit</button>
</form>
The form-validation.php file
The file contains the PHP form validation code.
<?php
// Initializing the error variables to null.
$firstname_error = null;
$email_error = null;
$profile_description_error = null;
$fav_color_error = null;
$gender_error = null;
$fav_food_error = null;
$success_message = null;
// Checking if the form is submitted using the POST HTTP method.
if($_SERVER["REQUEST_METHOD"] == "POST"){
// Storing the form data that the $_POST array holds in a variable
// named $user_data so it makes more sense.
$user_data = $_POST;
// First name validation.
if(empty($user_data['firstname'])){
// Display error message if first name is empty.
$firstname_error = "Please enter your firstname";
}
// Only space, upper and lower case letters are allowed.
else if(!preg_match("/^[a-zA-Z ]+$/", $user_data["firstname"])){
$firstname_error = "The field accepts only alphabetic characters";
}
// Email Validation.
else if(empty($user_data['email'])){
// Display error if email field is empty.
$email_error = "Please fill in your email";
}
else if(!filter_var($user_data['email'], FILTER_VALIDATE_EMAIL)){
// Display error if email is not properly formatted.
$email_error = "Please enter a valid email address";
}
// Profile description validation.
else if(empty($user_data['profile-description'])){
// Display error if textarea is empty.
$profile_description_error = "Please write a few words about you";
}
// Validating the select menu.
else if(empty($user_data['fav-color'])){
// Display error if no favorite color option is selected.
$fav_color_error = "Please select your favorite color";
}
// Validating radio buttons.
else if(!isset($_POST['gender'])){
// Display error when no gender is selected.
$gender_error = "Please select your gender";
}
// Validating the check boxes.
// Remember that the $_POST['fav_foods'] is an array holding the
// values from the checked checkboxes.
else if(!isset($_POST['fav_foods'])){
// Display error when no favorite food is selected.
$fav_food_error = "Please select at least one fav-food";
}
// Collecting the values
else{
$firstname = trim($_POST['firstname']);
// Using the htmlspecialchars function we sanitize the user input.
// Using the trim function we remove any white space from the start
// and the end of a string.
$email = htmlspecialchars(trim($_POST['email']));
$profile_description = htmlspecialchars(trim($_POST['profile-description']));
$favorite_color = htmlspecialchars(trim($_POST['fav-color']));
$gender = htmlspecialchars(trim($_POST['gender']));
// Using the implode function we convert the $_POST['fav_foods'] array
// in a string separating each value with a comma.
$favorite_foods = implode(',', $_POST['fav_foods']);
// Now we can put the user data in the database, or store them
// in a JSON file or send them where they are required.
// And when everything goes well we display a success message.
$success_message = "Your profile data where successfully submitted";
}
}
The styles.css file
Copy and paste the CSS code to your styles.css file to apply the same styling as the live demo form.
*{
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: Ubuntu;
}
body{
min-height: 100%;
color: #555;
background-color: #fff;
}
h1{
text-align: center;
margin-top: 30px;
margin-bottom: 30px;
color: #555;
font-size: 40px;
}
form{
border: thin solid #e4e4e4;
padding: 0 20px 20px 20px;
box-shadow: 0 5px 5px rgba(0, 0, 0, 0.2);
width: 500px;
margin: 0 auto;
}
form label{
display: block;
margin-bottom: 10px;
margin-top: 30px;
color: #32749a;
font-size: 16px;
}
form input, form textarea{
display: block;
width: 100%;
padding: 10px;
font-size: 18px;
border: thin solid #e4e4e4;
}
form select{
display: block;
width: 100%;
margin-bottom: 10px;
padding: 10px;
font-size: 18px;
border: thin solid #e4e4e4;
background-color: white;
color: #555;
}
form input:focus,
form select:focus,
form textarea
{
outline: none;
}
form textarea{
min-height: 80px;
}
form input::placeholder{
font-size: 16px;
}
form button{
background: #32749a;
color: white;
border: none;
padding: 15px;
width: 100%;
font-size: 20px;
margin-top: 40px;
cursor: pointer;
}
form button:active{
background-color: green;
}
.radio-buttons{
margin-top: 40px;
}
.radio-buttons input{
display: inline-block;
width: auto;
}
.radio-buttons span{
padding-left: 20px;
}
.radio-buttons span:nth-child(2){
padding-left: 0;
}
.checkboxes{
margin-top: 20px;
}
.checkboxes input{
width: auto;
display: inline-block;
}
.checkboxes span{
padding-left: 20px;
}
.checkboxes span:nth-child(2){
padding-left: 0;
}
.out{
font-size: 17px;
line-height: 28px;
}
.out span{
font-weight: bold;
color: #32749a;
}
.error{
margin-top: 10px;
color: #af0c0c;
background-color: #ffe7eb;
padding: 10px;
/* display: none;*/
line-height: 24px;
}
.success{
margin-top: 30px;
background-color: #dbffdb;
padding: 10px;
color: green;
}
Summary
In this tutorial I showed you how to handle form data with PHP using all the common form elements, like input fields, textarea, select menu, radio buttons, and check-boxes.
🎓 What you'll learnt in this tutorial:
- How to structure an HTML form to display error messages under every input field.
- How to preserve the user input in case of an error, so the user don't have to type the values again.
- How to group check-boxes together by using an array as a value in the name attribute, name="fav_foods[]"
- How to validate and sanitize the user's input in the PHP file.
- How to use the htmlspecialchars function, and the trim function to sanitize user input, and more ....
Source code
You can download the source code and use it in any way you like.
Times downloaded: 3