PHP Form Validation

Summary: in this tutorial, you’ll learn about PHP form validation, how to validate form data, and how to show error messages if the user inputs are invalid.

Introduction to PHP form validation #

When processing a form, it’s critical to validate user inputs to ensure that the data is in a valid format.

There are two types of validations:

  • Client-side validation
  • Server-side validation

The client-side validation provides instant feedback to the user, while the server-side validation can ensure that all data is valid before processing such as saving to database.

To validate data at the client side, you can use HTML5 validation or JavaScript.

The server-side validation validates data in the server using PHP.

To validate data in PHP, you can use filters with the following filter funtions:

Validating emails #

The following shows how to check if the email is in the POST request and validate it:

<form action="<?= htmlspecialchars($_SERVER['PHP_SELF']) ?>" method="post">
    <div>
        <label for="email">Email:</label>
        <input type="text" name="email">
        <button type="submit">Submit</button>
    </div>
</form>

<?php 

if($_SERVER['REQUEST_METHOD'] === 'POST') {
    // Check if the email field is set and not empty
    if(filter_has_var(INPUT_POST, 'email')) {
        // validate email
        $email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
        if($email !== false) {
            echo "Email is valid: " . htmlspecialchars($email);
        } else {
            echo "Invalid email format." . $_POST['email'];
        }
    } 
}Code language: PHP (php)

How it works.

First, check if the email is in the POST request using the filter_has_var function:

if(filter_has_var(INPUT_POST, 'email')) {Code language: PHP (php)

Second, validate email using the filter_input function with the filter id FILTER_VALIDATE_EMAIL:

$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);Code language: PHP (php)

If the email is not valid, the filter_input function returns false. If the email is valid, then the function returns the email.

Third, display an error message if the email is not valid or a success message otherwise:

if($email !== false) {
   echo "Email is valid: " . htmlspecialchars($email);
} else {
   echo "Invalid email format." . $_POST['email'];
}Code language: PHP (php)

Validating integers #

The following form requests you to enter your age and validate it as an integer with the valid range of (0,150):

<?php 

if($_SERVER['REQUEST_METHOD'] === 'POST') {
    // Check if the age field is set and not empty
    if(filter_has_var(INPUT_POST, 'age')) {
        // validate age between 0 and 150
        $age = filter_input(INPUT_POST, 'age', FILTER_VALIDATE_INT, [
            'options' => [
                'min_range' => 0,
                'max_range' => 150
            ]
        ]);

        if($age !== false) {
            echo "Age is valid: " . htmlspecialchars($age);
        } else {
            echo "Age is not valid:" . $_POST['age'];
        }
    } 
}
?> 

<form action="<?= htmlspecialchars($_SERVER['PHP_SELF']) ?>" method="post">
    <div>
        <label for="age">Age:</label>
        <input type="text" name="age" placeholder="Enter your age">
        <button type="submit">Submit</button>
    </div>
</form>
Code language: PHP (php)

How it works.

First, check if the age is in the POST request using the filter_has_var function:

if(filter_has_var(INPUT_POST, 'age')) {Code language: PHP (php)

Second, validate age using the filter_input function with the filter id FILTER_VALIDATE_INT:

$age = filter_input(INPUT_POST, 'age', FILTER_VALIDATE_INT, [
            'options' => [
                'min_range' => 0,
                'max_range' => 150
            ]
]);Code language: PHP (php)

The options limits the range of the age between 0 and 150.

If the age is not valid, the filter_input function returns false. If the age is valid, then the function returns the age.

Third, display an error message if the age is not valid or a success message otherwise:

if($age !== false) {
    echo "Age is valid: " . htmlspecialchars($age);
} else {
    echo "Age is not valid:" . $_POST['age'];
}Code language: PHP (php)

Validating floats #

The following form requests you to enter your weight and validate it as a float with the valid range of (0,300):

<?php 

if($_SERVER['REQUEST_METHOD'] === 'POST') {
    // Check if the weight field is set and not empty
    if(filter_has_var(INPUT_POST, 'weight')) {
        // validate weight between 0 and 150
        $weight = filter_input(INPUT_POST, 'weight', FILTER_VALIDATE_FLOAT, [
            'options' => [
                'min_range' => 0,
                'max_range' => 300

            ]
        ]);

        if($weight !== false) {
            echo "Weight is valid: " . htmlspecialchars($weight);
        } else {
            echo "Weight is not valid:" . $_POST['weight'];
        }
    } 
}
?> 

<form action="<?= htmlspecialchars($_SERVER['PHP_SELF']) ?>" method="post">
    <div>
        <label for="weight">Weight:</label>
        <input type="text" name="weight" placeholder="Enter your weight in lbs">
        <button type="submit">Submit</button>
    </div>
</form>
Code language: PHP (php)

How it works.

First, check if the weight is in the POST request using the filter_has_var function:

if(filter_has_var(INPUT_POST, 'weight')) {Code language: PHP (php)

Second, validate the weight using the filter_input function with the filter id FILTER_VALIDATE_FLOAT:

$weight = filter_input(INPUT_POST, 'weight', FILTER_VALIDATE_FLOAT, [
            'options' => [
                'min_range' => 0,
                'max_range' => 300

            ]
]);Code language: PHP (php)

The options limits the range of the weight between 0 and 300.

If the weight is not valid, the filter_input function returns false. If the weight is valid, then the function returns the weight as a float.

Note that the filter FILTER_VALIDATE_FLOAT trims the input before validating.

Third, display an error message if the weight is not valid or a success message otherwise:

if ($weight !== false) {
    echo "Weight is valid: " . htmlspecialchars($weight);
} else {
    echo "Weight is not valid:" . $_POST["weight"];
}Code language: PHP (php)

PHP form validation example #

We’ll build an email subscription form that includes a validation feature. The form has the name and email input elements and a submit button:

PHP form validation

If you don’t enter the name and/or email and click the subscribe button, the form will show the error messages. Also, if you enter an invalid email address, the form will show a different error message.

Notice that we don’t use the client-side validation for this form to make it easier to test. In practice, you should also use client-side validation.

Organize the directory and files #

First, create a file and directory structure as follows:

.
├── css
│   └── style.css
├── inc
│   ├── get.php
│   ├── post.php
│   ├── header.php
│   ├── footer.php
│   └── .htaccess
└── index.phpCode language: plaintext (plaintext)

The following table describes the purpose of each file:

FileDirectoryDescription
index.php.Contain the main logic of the form
header.phpincContain the header code
footer.phpincContain the footer code
get.phpincContain the email subscription form
post.phpincContain the code for handling form submission
style.csscssContain the CSS code

header.php #

The following shows the header.php file:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="css/style.css">
    <title>Subscribe</title>
</head>
<body>
    <main>Code language: PHP (php)

The header.php file link to the style.css file in the css directory.

And the footer.php only contains the enclosing tags that correspond to the opening tags in the header.php file:

</main>
</body>
</html>Code language: PHP (php)

index.php #

The index.php file contains the main logic of the form:

<?php

require __DIR__ . '/inc/header.php';

$errors = [];
$inputs = [];

$request_method = strtoupper($_SERVER['REQUEST_METHOD']);

if ($request_method === 'GET') {
    // show the form
    require __DIR__ . '/inc/get.php';
} elseif ($request_method === 'POST') {
    // handle the form submission
    require    __DIR__ .  '/inc/post.php';
    // show the form if the error exists
    if (count($errors) > 0) {
        require __DIR__ . '/inc/get.php';
    }
}

require __DIR__ .  '/inc/footer.php';Code language: PHP (php)

How the index.php works.

First, load code from both header.php and footer.php files using the require construct at the top and bottom of the file to generate the header and footer.

Second, define the $errors array to store error messages and the $inputs array to store the entered form values. If an input element has invalid data, the index.php will show the entered value stored in the $inputs.

Third, show the form if the HTTP request method is GET by loading the get.php file. Once you enter the

Finally, load the code in the post.php to handle the form submission if the HTTP request method is POST. If the form has any errors, the $errors will not empty. In this case, show the form again with the error messages stored in the $errors array and entered values stored in the $inputs arrays.

get.php #

The get.php file contains the form:

<form action="<?php echo htmlspecialchars($_SERVER['PHP_SELF']) ?>" method="post">
    <header>
        <h1>Get FREE Updates</h1>
        <p>Join us for FREE to get email updates!</p>
    </header>
    <div>
        <label for="name">Name:</label>
        <input type="text" name="name" id="name" placeholder="Full Name" value="<?php echo $inputs['name'] ?? '' ?>" class="<?php echo isset($errors['name']) ? 'error' : ''  ?>">
        <small><?php echo $errors['name'] ?? '' ?></small>
    </div>
    <div>
        <label for="name">Email:</label>
        <input type="text" name="email" id="email" placeholder="Email Address" value="<?php echo $inputs['email'] ?? '' ?>" class="<?php echo isset($errors['email']) ? 'error' : '' ?>">
        <small><?php echo $errors['email'] ?? '' ?></small>
    </div>
    <button type="submit">Subscribe</button>
</form>Code language: PHP (php)

How the get.php works.

  • First, fill the name and email input elements with the entered values stored in the $inputs array only if these values exist.
  • Second, show the error messages stored in the $errors array if they exist.

post.php #

The following shows the code of the post.php file. The post.php validates the form data using the filter_input() and filter_var() functions.

<?php

const NAME_REQUIRED = 'Please enter your name';
const EMAIL_REQUIRED = 'Please enter your email';
const EMAIL_INVALID = 'Please enter a valid email';


// sanitize and validate name
if(filter_has_var(INPUT_POST, 'name')) {
    $name = htmlspecialchars($_POST['name']);
    if($name === '') {
        $errors['name'] = NAME_REQUIRED;
    } else {
        $inputs['name'] = $name;
    }

} else {
    $errors['name'] = NAME_REQUIRED;
}

if(filter_has_var(INPUT_POST, 'email')) {
    // sanitnize email first
    $email = filter_input(INPUT_POST, 'email', FILTER_SANITIZE_EMAIL);
    $inputs['email'] = $email;
    if($email) {
        // validate email
        $email = filter_var($email, FILTER_VALIDATE_EMAIL);
        // email is not valid
        if($email === false) {
            $errors['email'] = EMAIL_INVALID;
        } 
    } else {
        $errors['email'] = EMAIL_REQUIRED;
    } 
    
} else {
    $errors['email'] = EMAIL_REQUIRED;
}


?>

<?php if (count($errors) === 0) : ?>
    <section>
        <h2>
            Thanks <?php echo htmlspecialchars($name) ?> for your subscription!
        </h2>
        <p>Please follow the steps below to complete your subscription:</p>
        <ol>
            <li>Check your email (<?php echo htmlspecialchars($email) ?>) - Find the message sent from [email protected]</li>
            <li>Click to confirm - Click on the link in the email to confirm your subscription.</li>
        </ol>
    </section>

<?php endif ?>Code language: PHP (php)

How it works.

First, define some constants to store the error messages. In a real-world application, you can store all the messages in a separate file:

const NAME_REQUIRED = 'Please enter your name';
const EMAIL_REQUIRED = 'Please enter your email';
const EMAIL_INVALID = 'Please enter a valid email';Code language: PHP (php)

Second, sanitize and validate the name using the htmlspecialchars() function. If the name is empty, add an error message to the $errors array.

if(filter_has_var(INPUT_POST, 'name')) {
    $name = htmlspecialchars($_POST['name']);
    if($name === '') {
        $errors['name'] = NAME_REQUIRED;
    } else {
        $inputs['name'] = $name;
    }

} else {
    $errors['name'] = NAME_REQUIRED;
}Code language: PHP (php)

Third, sanitize and validate email using the filter_input() and filter_var() functions. If the email is empty or invalid, add the corresponding error message to the $errors array.

// sanitize and validate email
if(filter_has_var(INPUT_POST, 'email')) {
    // sanitnize email first
    $email = filter_input(INPUT_POST, 'email', FILTER_SANITIZE_EMAIL);
    $inputs['email'] = $email;
    if($email) {
        // validate email
        $email = filter_var($email, FILTER_VALIDATE_EMAIL);
        // email is not valid
        if($email === false) {
            $errors['email'] = EMAIL_INVALID;
        } 
    } else {
        $errors['email'] = EMAIL_REQUIRED;
    } 
    
} else {
    $errors['email'] = EMAIL_REQUIRED;
}Code language: PHP (php)

Finally, if the form has no error, show the confirmation message:

<?php if (count($errors) === 0) : ?>
    <section>
        <h2>
            Thanks <?php echo htmlspecialchars($name) ?> for your subscription!
        </h2>
        <p>Please follow the steps below to complete your subscription:</p>
        <ol>
            <li>Check your email (<?php echo htmlspecialchars($email) ?>) - Find the message sent from [email protected]</li>
            <li>Click to confirm - Click on the link in the email to confirm your subscription.</li>
        </ol>
    </section>
<?php endif ?>Code language: PHP (php)

To complete the form, you can save the contact data to a database or call an API of an email marketing service to add the contact to your list.

Summary #

  • Use the filter_has_var() function to check if variables exists in the INPUT_POST.
  • Use the filter_input() function to sanitize and validate data.
Did you find this tutorial useful?