How to Set up PHP Form Validation – Detailed Tutorial

On March 04, 2024
11min read
Veljko Ristić Content Manager @ Mailtrap
This is an illustration for an article that offers a detailed PHP form validation tutorial.

PHP form validation helps maintain data integrity and security, preventing SQL injection, XSS, and other malicious attacks. 

From the user input perspective, it prevents issues such as storing incorrect or incomplete data in the database. Plus, users can get immediate feedback about the input’s correctness, which improves their experience with your product. 

In this article, we’ll cover different types of validation for a simple registration form, starting with a quick overview of the available options.

Choosing a PHP form validation method

There are a few options to validate a PHP form – you can use a PHP script, Ajax, JS, or a database. 

I’ll briefly cover the benefits and challenges of each. Then, we’ll move to integration tutorials, including exemplary scripts.

Benefits:

  • Flexibility and control over the validation process.
  • Scripts can automate repetitive tasks such as data cleaning or analysis after form submission.
  • They allow for custom processing and logic that may not be possible with standard form handling.

Challenges:

  • Custom scripts require maintenance and updates as requirements change or technology evolves.
  • Potential for security vulnerabilities if not implemented securely.

AJAX validation 

Benefits:

  • AJAX allows asynchronous form submissions without page refreshes, providing a smoother user experience. 
  • It enables real-time validation and feedback, which can improve user engagement and reduce errors. 

Challenges:

  • AJAX can add complexity to the development process due to specific syntax and logic.  May be challenging for developers unfamiliar with JavaScript and asynchronous operations.
  • The functionality depends on JavaScript being enabled in the user’s browser, which may not always be the case. 
  • AJAX requests can be vulnerable to cross-site request forgery (CSRF) attacks unless properly secured.

JavaScript validation 

Benefits:

  • JavaScript provides immediate feedback to users, improving the user experience by catching errors before the form is submitted. 
  • By validating on the client side, you can reduce the load on your server since invalid forms won’t reach the server. 

Challenges:

  • Client-side validation can be easily bypassed by disabling JavaScript or manipulating the DOM, so it should never replace server-side validation. 
  • Not all browsers interpret JavaScript in the same way, which can lead to inconsistent behavior.
  • May not be accessible to users with disabilities who rely on assistive technologies that might not work well with JavaScript.

Database validation 

Benefits:

  • Storing form data in a database ensures that the data is persistent and can be accessed later for various purposes. 
  • Databases are designed to handle large amounts of data and can scale as needed.

Challenges:

  • Writing to a database can be slower than other methods and can impact performance, especially if the database is not optimized. 
  • Managing database connections and queries adds complexity to the application.

Note that the choice of method depends on the project’s specific needs, the resources available, and the development team’s expertise. 

Also, it’s important to implement multiple validation layers:

  • Client-side for user experience 
  • Server-side for security 
  • Database interaction for data persistence

By combining these layers and incorporating sanitization practices, you can build robust and secure forms that enhance your application’s functionality and user experience. Additionally, consider exploring server-side validation libraries for streamlined implementation and advanced features.

How to validate a form in PHP using script

I’ll start with a basic PHP validation script as it’s one of the quickest methods to implement. 

In this PHP tutorial, I won’t be adding any CSS to the HTML entities as the main focus is on the email form validation. 

Step 1 – Create an HTML form 

Design your form with the necessary fields and include a submit button.

<form method="post" action="validate.php">
    Name: <input type="text" name="name"><br>
    Email: <input type="text" name="email"><br>
    <input type="submit" name="submit" value="Submit">
</form>

Step 2 – Sanitize and validate Input 

At the beginning of your PHP script, sanitize and validate the input. Use the $_POST superglobal array to access the input field form data.

<?php
if ($_SERVER["REQUEST_METHOD"] === "POST") {
    // Sanitize and validate name
    $name = test_input($_POST["name"]);
    $nameErr = "";
    if (!preg_match("/^[a-zA-Z ]*$/",$name)) {
        $nameErr = "Only letters and white space allowed";
    }
    
    // Sanitize and validate email
    $email = test_input($_POST["email"]);
    $emailErr = "";
    if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        $emailErr = "Invalid email format";
    }
    
    // ... Additional validation checks ...
}

function test_input($data) {
    $data = trim($data);
    $data = stripslashes($data);
    $data = htmlspecialchars($data);
    return $data;
}
?>

Step 3 – Display Errors 

If there are validation errors, display them to the user. Otherwise, proceed with the form processing.

if ($nameErr != "" || $emailErr != "") {
    echo "<b>Error:</b>";
    echo "<br>" . $nameErr;
    echo "<br>" . $emailErr;
} else {
    // Process the form data
    echo "Form submitted successfully";
}

Pro Tips

  • To prevent XSS attacks and preserve data integrity, you can use the php echo htmlspecialchars function. It also makes the validation compatible with different encodings like UTF-8. Here’s the exemplary snippet:
$userInput = "<script>alert('Hello!');</script>";
echo htmlspecialchars($userInput, ENT_QUOTES, 'UTF-8');
  • If the form passes validation, you can process the data accordingly, such as inserting it into a database or sending an email. I’ll show you how to send an email later. 
  • To avoid repeating code, encapsulate the validation logic within functions or classes and reuse them across different forms.
  • As your application and validation needs grow, consider structuring the validation using OOP logic. It makes the code more modular, and easier to maintain, and it improves code organization. Check the example below.
class FormValidator {
    private $data;
    private $requiredFields = [];
    public function __construct($postData) {
        $this->data = $postData;
    }

    public function validate() {
        // Common validation rules
        $this->validateRequiredFields();
        $this->validateEmailFormat();
        // Add more validation methods as needed
    }

    private function validateRequiredFields() {
        // Check if required fields are present
        foreach ($this->requiredFields as $field) {
            if (empty($this->data[$field])) {
                throw new Exception("{$field} is required.");
            }
        }
    }

    private function validateEmailFormat() {
        // Check if email field is in a valid format
        if (!filter_var($this->data['email'], FILTER_VALIDATE_EMAIL)) {
            throw new Exception("Invalid email format.");
        }
    }

    // Define other validation methods...
}

// Usage
if ($_SERVER["REQUEST_METHOD"] === "POST") {
    $validator = new FormValidator($_POST);
    try {
        $validator->validate();
        // If validation passes, process the form
    } catch (Exception $e) {
        echo $e->getMessage();
    }
}
  • If necessary you can add a checkbox or a radio button to the form, then validate that input. Here’s an example:
<?php
if ($_SERVER["REQUEST_METHOD"] == "POST") {
    // Radio button validation
    if (!isset($_POST['gender']) || empty($_POST['gender'])) {
        echo "Gender selection is required.<br>";
    } else {
        $gender = $_POST['gender'];
        // You can add additional validation here if needed
    }

    // Checkbox validation
    if (!isset($_POST['terms']) || $_POST['terms'] !== 'agree') {
        echo "You must agree to the terms and conditions.<br>";
    } else {
        // User agreed to terms and conditions
    }

    // If no errors, process the form
    if (empty($errors)) {
        echo "Form submitted successfully.";
    }
}
?>

How to validate a form in PHP using AJAX

AJAX offers a smooth user experience indeed, but note that you’ll also need to implement server-side CSRF protection. I won’t be covering that in this article.  

Step1 – Create an HTML form 

Start with a simple form in your HTML file with the action set to a PHP script and the method set to POST.

<form id="contactForm" action="process.php" method="post">
    Name: <input type="text" name="name" required><br>
    Email: <input type="email" name="email" required><br>
    Message: <textarea name="message" required></textarea><br>
    <input type="submit" value="Submit">
</form>
<div id="response"></div>

Step 2 – Use Javascript for AJAX submission 

Write a native Javascript function that prevents the default form submission and sends the form data via AJAX to the server.

const form = document.getElementById('contactForm');

form.addEventListener('submit', function(event) {
  event.preventDefault();

  const formData = new FormData(form);

  fetch(form.action, {
    method: 'POST',
    body: formData
  })
  .then(response => response.text())
  .then(data => {
    document.getElementById('response').innerHTML = data;
  })
  .catch(error => {
    console.error('Error:', error);
  });
});

Step 3 – Handle form validation in PHP 

Create a process.php file to handle the form submission. Use PHP’s built-in functions like filter_var() to check for valid email address and trim() to remove extra spaces.

<?php
$name = trim(filter_input(INPUT_POST, 'name', FILTER_SANITIZE_STRING));
$email = trim(filter_input(INPUT_POST, 'email', FILTER_SANITIZE_EMAIL));
$message = trim(filter_input(INPUT_POST, 'message', FILTER_SANITIZE_STRING));

if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
    echo "Invalid email format";
} else {
      // Process the form data (using prepared statements for database interaction)

    echo "Form submitted successfully";
}
?>

How to validate a form in PHP using JavaScript

Similar to AJAX, JS is great for improved user experience, but you’ll still need to make sure the method can’t be manipulated. So it’s wise to implement server-side validation as well. 

Step 1 – Create an HTML form 

Similar to the AJAX example, create a form in your HTML file.

<form id="contactForm" action="process.php" method="post">
    <!-- form fields -->
    <input type="submit" value="Submit">
</form>
<div id="error"></div>

Step 2 – Implement JavaScript validation 

Add a JavaScript function to validate the form fields before submission.

function validateForm() {
    var email = document.forms["contactForm"]["email"].value;
    var errorDiv = document.getElementById("error");

    if (!validateEmail(email)) {
        errorDiv.innerHTML = "Invalid email format";
        return false;
    } else {
        errorDiv.innerHTML = "";
        return true;
    }
}

function validateEmail(email) {
    var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
    return re.test(String(email).toLowerCase());
}

Ensure that you also validate the data on the server side using PHP, as client-side validation can be bypassed. And make sure your PHP file is properly protected.

Important Note:

The validation script contains a mile-long regex. It works, but it’s not exactly an example of best coding practice, and in a real-world scenario, you’d want to use a JS validation library to avoid false positives or negatives. Here’s an example with the email-validator lib:

// Import the email-validator library
var validator = require('email-validator');

function validateForm() {
    var email = document.forms["contactForm"]["email"].value;
    var errorDiv = document.getElementById("error");

    if (!validator.validate(email)) {
        errorDiv.innerHTML = "Invalid email format";
        return false;
    } else {
        errorDiv.innerHTML = "";
        return true;
    }
}

PHP form validation: more use cases

Aside from what’s already covered, which is mostly email and name validation. There are several other form elements you may want to validate. Also, it’s advisable to include CAPTCHA with your forms to ward off bots. 

The quick tutorials below include CAPTCHA integration, empty field, phone number, and website validation. Depending on your specific use case, and the form you created, you probably won’t need all. 

CAPTCHA

As indicated, CAPTCHAs are used to verify that the user is human and not a bot. They typically involve solving a puzzle or identifying objects in images. Here’s how to integrate it. 

  1. Include a CAPTCHA library: Choose a library or service to generate the CAPTCHA image. Google’s reCAPTCHA is a popular choice.
  2. Generate CAPTCHA image: When the form is loaded, call the captcha library’s API to generate a captcha challenge.
  3. Embed CAPTCHA in the form: Display the CAPTCHA image in your form where users can see it.
  4. Validate CAPTCHA response: When the form is submitted, check the user’s response against the CAPTCHA library’s verification API.
  5. Handle verification result: If the captcha was solved correctly, continue processing the form. Otherwise, display an error message.

Code examples

  • HTML form
<form method="post" action="validate.php">
    <!-- Other form fields -->
    <img src="captcha.php" alt="CAPTCHA Image">
    Enter the code above: <input type="text" name="captcha">
    <input type="submit" value="Submit">
</form>
  • PHP (validate.php)
<?php
session_start();
if ($_SERVER["REQUEST_METHOD"] == "POST") {
    $captcha_code = $_SESSION['captcha_code'];
    $user_entered_code = $_POST['captcha'];
    if ($captcha_code == $user_entered_code) {
        // Continue processing the form
    } else {
        echo "Captcha code is incorrect.";
    }
}
?>
  • PHP (captcha.php)
<?php
session_start();
$random_number = bin2hex(random_bytes(4));
$_SESSION['captcha_code'] = $random_number;
header("Content-type: image/png");
$image = imagecreatetruecolor(80,  30);
$font_size =  14;
$font_file = 'arial.ttf';
$width = ImageFontWidth($font_size) * strlen($random_number);
$height = ImageFontHeight($font_size);
$image_width = 80;
$image_height = 30;
$text_color = imagecolorallocate($image, 0, 0, 0);
$x = ceil(($image_width - $width)/2);
$y = ceil(($image_height - $height)/2);
ImageString($image, $font_size, $x, $y, $random_number, $text_color);
ImagePNG($image);
ImageDestroy($image);
?>

Empty field

Empty fields can occur when a user does not fill out a required input. These inputs shouldn’t be processed, and you need to inform the user about it. Here’s the process. 

  1. Mark required fields: Use the required attribute in your HTML form to indicate mandatory fields.
  2. Check for empty values: In your PHP script, check if the required fields are empty using empty().
  3. Show error messages: If a required field is empty, display an error message prompting the user to fill it out.
  4. Prevent form submission: If there are any errors, stop the form submission process.

Code examples

  • HTML form
<form method="post" action="validate.php">
    Name: <input type="text" name="name" required><br>
    Email: <input type="email" name="email" required><br>
    <input type="submit" value="Submit">
</form>
  • PHP (validate.php)
<?php
if ($_SERVER["REQUEST_METHOD"] == "POST") {
    $name = $_POST['name'];
    $email = $_POST['email'];
    $errors = [];
    if (empty($name)) {
        $errors[] = "Name is required.";
    }
    if (empty($email)) {
        $errors[] = "Email is required.";
    }
    if (!empty($errors)) {
        foreach ($errors as $error) {
            echo $error . "<br>";
        }
    } else {
        // No errors, process the form
    }
}
?>

Phone number

Phone numbers are often required for contact information, and they need to be formatted consistently. Otherwise, you could be dealing with wrong or misleading info in your CRM system. Here’s an exemplary flow. 

  1. Design a form with a phone number field
  2. Sanitize and format input: Use PHP’s filter_var() function with the FILTER_SANITIZE_NUMBER_INT flag to remove non-numeric characters.
  3. Validate length and format: Use a regular expression to check the length and format of the phone number.
  4. Handle validation results: If the phone number is not valid, display an error message.

Code examples

  • HTML form
<form method="post" action="validate.php">
    Phone Number: <input type="tel" name="phone" pattern="[0-9]{3}-[0-9]{3}-[0-9]{4}" required><br>
    <input type="submit" value="Submit">
</form>
  • PHP (validate.php)
<?php
if ($_SERVER["REQUEST_METHOD"] == "POST") {
    $phone = $_POST['phone'];
    $phone = filter_var($phone, FILTER_SANITIZE_NUMBER_INT);
    if (!preg_match('/^\d{3}-\d{3}-\d{4}$/', $phone)) {
        echo "Invalid phone number format. Please use xxx-xxx-xxxx.";
    } else {
        // Valid phone number, process the form
    }
}
?>

Website URL

As website URLs are used to direct users to external websites, it’s important to validate them to ensure they are correctly formatted and safe to navigate to. 

  1. Design form with website URL field 
  2. Sanitize input: Use PHP’s filter_var() function with the FILTER_SANITIZE_URL flag to sanitize the URL input.
  3. Validate URL format: Use filter_var() with the FILTER_VALIDATE_URL flag to check if the input is a valid URL.
  4. Handle validation results: If the URL is not valid, display an error message.

Code examples

  • HTML form
<form method="post" action="validate.php">
    Website: <input type="url" name="website" pattern="https?://.+" title="Enter a valid URL"><br>
    <input type="submit" value="Submit">
</form>
  • PHP (validate.php)
<?php
if ($_SERVER["REQUEST_METHOD"] == "POST") {
    $website = $_POST['website'];
    $website = filter_var($website, FILTER_SANITIZE_URL);
    if (!filter_var($website, FILTER_VALIDATE_URL)) {
        echo "Invalid website URL.";
    } else {
        // Valid URL, process the form
    }
}
?>

In this example, the HTML form includes a pattern attribute for the URL input to encourage the entry of a valid URL in the browser’s UI. Nevertheless, it’s still important to validate on the server side because client-side validation can be bypassed. 

The PHP script sanitizes the input to remove any potentially harmful characters and then validates it to ensure it’s a proper URL format. If the URL passes both sanitation and validation, you can proceed with processing the form data.

PHP form is valid? Send an email!

This section assumes you have already implemented server-side form validation to ensure the integrity of data before sending an email. And it focuses on sending confirmation emails after successful form submission.

After validating a form you can send an email confirmation to the user or the administrator. To do this, I’ll use the Mailtrap Email Sending which is part of the Maitrap Email Delivery Platform

Check the video below ⬇️ to see Mailtrap Email Sending in action.

Mailtrap offers PHP SDK, and I’ll be using that for this integration since it’s the most convenient option. 

But Mailtrap also offers SMTP setup and the corresponding email sending. We already blogged about that, and you can check the full tutorials in this article

Here’s a quick tutorial for the SDK method.

  • Use Composer to install the Mailtrap PHP SDK in your project.
composer require railsware/mailtrap-php symfony/http-client nyholm/psr7
  • Initialize the Mailtrap client with your API key.
<?php
use Mailtrap\Config;
use Mailtrap\MailtrapClient;

$apiKey = getenv('MAILTRAP_API_KEY');
$mailtrap = new MailtrapClient(new Config($apiKey));
  • To compose an email, create an instance of Symfony\Component\Mime\Email with the sender, recipient, subject, and content.
use Symfony\Component\Mime\Email;

$email = (new Email())
    ->from(new Address('no-reply@your-domain.com', 'Your App'))
    ->to(new Address('recipient@example.com', 'Recipient Name'))
    ->subject('Thank you for signing up!')
    ->text('We received your registration details. Thank you for signing up!');
  • Use the Mailtrap client to send the email.
try {
    $response = $mailtrap->sending()->emails()->send($email);
    var_dump(ResponseHelper::toArray($response));
} catch (Exception $e) {
    echo 'Caught exception: ',  $e->getMessage(), "\n";
}

Do you need to test email confirmations before sending them?

I’d say yes, you need to test, particularly if you’re sending confirmations to your users. And, I’ll use Mailtrap Email Testing – a sandbox solution to inspect and debug emails in staging, dev, and QA environments before sending them to recipients. 

To stress, this is a sandbox environment, so your emails will land in Mailtrap Inbox for further inspection, they won’t be sent to users on production servers.

The setup is straightforward, and Mailtrap Email Testing offers integrations in 20+ languages, including PHP. Here I’ll show you a quick example of how to integrate with PHPMailer. Of course, I assume that you’re already a user, if not, click here to sign up.

  • In your transport method, specify Mailtrap SMTP credentials.
Host: sandbox.smtp.mailtrap.io
Port: 25 or 465 or 587 or 2525
Username: unique for each Mailtrap inbox
Password: unique for each Mailtrap inbox
TLS: Optional (STARTTLS on all ports)
  • Specify PHPMailer integration.
<?php
// ...
$mail->isSMTP();
$mail->Host = 'sandbox.smtp.mailtrap.io';
$mail->SMTPAuth = true;
$mail->Username = '1a2b3c4d5e6f7g'; //paste one generated by Mailtrap
$mail->Password = '1a2b3c4d5e6f7g' //paste one generated by Mailtrap
$mail->SMTPSecure = 'tls';
$mail->Port = 2525;

Note that Mailtrap Email Testing also has a RESTful API that allows you to automate the testing process.

Data validity galore

PHP form validation plays a crucial role in ensuring the quality and security of the data you collect. By implementing various validation techniques like server-side validation, client-side validation, and specific validations for different data types (e.g., email format, phone number format), you can build user trust, prevent invalid data entry, and maintain data accuracy.

I encourage you to explore the resources mentioned throughout this guide for further learning and advanced functionalities. Additionally, consider delving deeper into areas like implementing CAPTCHAs for enhanced security or utilizing specialized data validation libraries for various data types

Article by Veljko Ristić Content Manager @ Mailtrap

Linguist by trade, digital marketer at heart, I’m a Content Manager who’s been in the online space for 10+ years. From ads to e-books, I’ve covered it all as a writer, editor, project manager, and everything in between. Now, my passion is with email infrastructure with a strong focus on technical content and the cutting-edge in programming logic and flows. But I still like spreading my gospels while blogging purely about marketing.