Form validation checks user-submitted data before processing it or storing it in a database.
- PHP provides functions such as empty(), filter_var(), and preg_match() to validate form inputs.
- Validation helps ensure that submitted data follows the expected format and meets application requirements.
- Server-side validation is essential because client-side validation can be bypassed.
- Invalid input should produce appropriate error messages instead of being processed.
Types of Form Validation in PHP
PHP supports different types of form validation depending on the input field and the application's requirements.
1. Empty Field Validation
Empty field validation checks whether a required input field contains a value. PHP's empty() function can be used to check whether a variable is empty.
<?php
$userName = trim($_POST['userName'] ?? '');
if ($userName === '') {
$errorMsg = "Username is required.";
} else {
echo htmlspecialchars($userName, ENT_QUOTES, 'UTF-8');
}
?>
In this example, trim() removes leading and trailing whitespace, while the condition checks whether the username is empty.
2. String Validation
String validation checks whether a value follows a specified pattern. PHP's preg_match() function can validate usernames containing only letters, numbers, and underscores.
<?php
$userName = trim($_POST['userName'] ?? '');
if (!preg_match('/^[a-zA-Z0-9_]+$/', $userName)) {
$errorMsg = "Username can contain only letters, numbers, and underscores.";
} else {
echo htmlspecialchars($userName, ENT_QUOTES, 'UTF-8');
}
?>
The + quantifier requires at least one character. Add a separate length check if the username must follow a specific length range.
3. Numeric Validation
Numeric validation checks whether an input contains a valid number or consists only of digits. For fields such as phone numbers, preg_match() can ensure that the input contains digits only.
<?php
$phoneNo = trim($_POST['phoneNo'] ?? '');
if (!preg_match('/^[0-9]+$/', $phoneNo)) {
$errorMsg = "Phone number must contain digits only.";
} else {
echo htmlspecialchars($phoneNo, ENT_QUOTES, 'UTF-8');
}
?>
This example checks the format but does not enforce a specific number of digits. Phone numbers should generally be treated as strings rather than integers because they may contain leading zeros.
4. Email Validation
Email validation checks whether an email address follows a valid format. PHP's filter_var() function with the FILTER_VALIDATE_EMAIL filter provides a convenient way to perform this check.
<?php
$emailID = trim($_POST['emailID'] ?? '');
if (!filter_var($emailID, FILTER_VALIDATE_EMAIL)) {
$errorMsg = "Please enter a valid email address.";
} else {
echo htmlspecialchars($emailID, ENT_QUOTES, 'UTF-8');
}
?>
This validates the email address's format but does not guarantee that the address exists or can receive emails.
5. String Length Validation
String length validation checks whether an input meets a required length. PHP's strlen() function returns the number of bytes in a string, making it suitable for checking the length of an ASCII-only numeric phone number.
<?php
$phoneNo = trim($_POST['phoneNo'] ?? '');
if (!preg_match('/^[0-9]{10}$/', $phoneNo)) {
$errorMsg = "Phone number must contain exactly 10 digits.";
} else {
echo htmlspecialchars($phoneNo, ENT_QUOTES, 'UTF-8');
}
?>
The regular expression requires exactly 10 digits, combining numeric and length validation in one check.
6. URL Validation
URL validation checks whether a submitted value follows a valid URL format. PHP's filter_var() function with FILTER_VALIDATE_URL can perform this validation.
<?php
$url = trim($_POST['website'] ?? '');
if ($url !== '' && !filter_var($url, FILTER_VALIDATE_URL)) {
$errorMsg = "Please enter a valid URL.";
} else {
echo htmlspecialchars($url, ENT_QUOTES, 'UTF-8');
}
?>
This example treats the URL field as optional. If a URL is provided, it must pass validation. FILTER_VALIDATE_URL does not verify that the website exists or is reachable.
7. Button Click Validation
PHP's isset() function can check whether a submit button's name is present in the submitted form data.
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
echo "The form has been submitted.";
}
?>
Checking the request method is generally more appropriate when processing a form because it does not depend on the name of a particular submit button.
Steps to Implement Form Validation
A registration form can combine multiple validation rules to check user input before displaying the submitted details.
The following steps demonstrate how to validate a username, email address, phone number, website URL, gender selection, and terms-and-conditions checkbox.
- Create an HTML form containing the required input fields.
- Retrieve the submitted values using the $_POST superglobal.
- Validate each field using appropriate PHP functions.
- Display error messages for invalid inputs.
- Process and display the submitted details only when all validation checks pass.
Implement Form Validation
Create a file named index.php and add the following code. It handles both the form and its validation logic.
* {
box-sizing: border-box;
}
body {
font-family: Arial, sans-serif;
background-color: #f4f4f4;
margin: 0;
padding: 30px 15px;
}
.container {
max-width: 500px;
margin: 0 auto;
padding: 25px;
background-color: #ffffff;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}
h2 {
text-align: center;
margin-top: 0;
}
form {
display: flex;
flex-direction: column;
gap: 8px;
}
label {
font-weight: bold;
}
input[type="text"] {
width: 100%;
padding: 10px;
border: 1px solid #cccccc;
border-radius: 4px;
}
.radio-group {
display: flex;
flex-wrap: wrap;
gap: 15px;
}
.radio-group label,
.checkbox-label {
display: flex;
align-items: center;
gap: 6px;
font-weight: normal;
}
.error {
color: #c62828;
font-size: 14px;
margin-bottom: 6px;
}
button {
padding: 11px;
margin-top: 10px;
background-color: #007bff;
color: #ffffff;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
}
button:hover {
background-color: #0056b3;
}
.success {
margin-top: 20px;
padding: 12px;
color: #155724;
background-color: #d4edda;
border: 1px solid #c3e6cb;
border-radius: 4px;
}
<?php
require_once "validation.php";
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>PHP Form Validation</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">
<h2>Registration Form</h2>
<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"], ENT_QUOTES, "UTF-8"); ?>">
<label for="username">Username:</label>
<input
type="text"
id="username"
name="username"
value="<?php echo htmlspecialchars($username, ENT_QUOTES, "UTF-8"); ?>"
>
<span class="error"><?php echo $usernameErr; ?></span>
<label for="email">Email:</label>
<input
type="text"
id="email"
name="email"
value="<?php echo htmlspecialchars($email, ENT_QUOTES, "UTF-8"); ?>"
>
<span class="error"><?php echo $emailErr; ?></span>
<label for="phone">Phone Number:</label>
<input
type="text"
id="phone"
name="phone"
value="<?php echo htmlspecialchars($phone, ENT_QUOTES, "UTF-8"); ?>"
>
<span class="error"><?php echo $phoneErr; ?></span>
<label for="website">Website (optional):</label>
<input
type="text"
id="website"
name="website"
value="<?php echo htmlspecialchars($website, ENT_QUOTES, "UTF-8"); ?>"
>
<span class="error"><?php echo $websiteErr; ?></span>
<label>Gender:</label>
<div class="radio-group">
<label>
<input
type="radio"
name="gender"
value="male"
<?php echo $gender === "male" ? "checked" : ""; ?>
>
Male
</label>
<label>
<input
type="radio"
name="gender"
value="female"
<?php echo $gender === "female" ? "checked" : ""; ?>
>
Female
</label>
<label>
<input
type="radio"
name="gender"
value="other"
<?php echo $gender === "other" ? "checked" : ""; ?>
>
Other
</label>
</div>
<span class="error"><?php echo $genderErr; ?></span>
<label class="checkbox-label">
<input
type="checkbox"
name="terms"
value="yes"
<?php echo $termsAccepted ? "checked" : ""; ?>
>
I agree to the terms and conditions.
</label>
<span class="error"><?php echo $termsErr; ?></span>
<button type="submit">Register</button>
</form>
<?php if ($isSubmitted && $isValid): ?>
<p class="success">Registration successful!</p>
<?php endif; ?>
</div>
</body>
</html>
<?php
// Initialize form values and error messages.
$username = "";
$email = "";
$phone = "";
$website = "";
$gender = "";
$termsAccepted = false;
$usernameErr = "";
$emailErr = "";
$phoneErr = "";
$websiteErr = "";
$genderErr = "";
$termsErr = "";
$isSubmitted = $_SERVER["REQUEST_METHOD"] === "POST";
$isValid = false;
// Process the form only after submission.
if ($isSubmitted) {
$username = input_data($_POST["username"] ?? "");
$email = input_data($_POST["email"] ?? "");
$phone = input_data($_POST["phone"] ?? "");
$website = input_data($_POST["website"] ?? "");
$gender = input_data($_POST["gender"] ?? "");
$termsAccepted = isset($_POST["terms"]) && $_POST["terms"] === "yes";
// Validate username.
if ($username === "") {
$usernameErr = "Username is required.";
} elseif (!preg_match("/^[a-zA-Z0-9_]{3,20}$/", $username)) {
$usernameErr = "Username must contain 3–20 letters, numbers, or underscores.";
}
// Validate email.
if ($email === "") {
$emailErr = "Email is required.";
} elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$emailErr = "Enter a valid email address.";
}
// Validate phone number.
if ($phone === "") {
$phoneErr = "Phone number is required.";
} elseif (!preg_match("/^[0-9]{10}$/", $phone)) {
$phoneErr = "Enter a valid 10-digit phone number.";
}
// Validate website only when provided.
if ($website !== "" && !filter_var($website, FILTER_VALIDATE_URL)) {
$websiteErr = "Enter a valid URL, including the scheme (e.g., https://example.com).";
}
// Validate gender.
if (!in_array($gender, ["male", "female", "other"], true)) {
$genderErr = "Please select a valid gender option.";
}
// Validate terms and conditions.
if (!$termsAccepted) {
$termsErr = "You must agree to the terms and conditions.";
}
// Check whether all validations passed.
$isValid = (
$usernameErr === "" &&
$emailErr === "" &&
$phoneErr === "" &&
$websiteErr === "" &&
$genderErr === "" &&
$termsErr === ""
);
}
// Remove extra whitespace from input.
function input_data($data) {
return trim((string) $data);
}
?>
Output: