Skip to content

PHP Form Validation

This chapter introduces essential techniques for validating user-submitted form data using PHP. Server-side validation is crucial for security and data integrity.

  • Security: Protect against common web vulnerabilities like Cross-Site Scripting (XSS), SQL Injection, and other malicious inputs.
  • Data Integrity: Ensure the data received is in the correct format and meets application requirements (e.g., valid email, required fields filled).
  • User Experience: Provide clear feedback to users about errors, helping them correct mistakes.

| | Think SECURITY when processing PHP forms! Proper validation and sanitization of form data on the server-side is non-negotiable. Never trust user input. Client-side validation (using HTML5 attributes or JavaScript) can improve UX but can be easily bypassed. | | --- | --- |

We’ll work with a form containing various input fields: required and optional text fields, radio buttons, and a submit button.

<!-- Simple form structure -->
<style>
.error { color: #FF0000; }
</style>
<h2>PHP Form Validation Example</h2>
<p><span class="error">* required field</span></p>
<form method="post" action="<?php echo htmlspecialchars($_SERVER['PHP_SELF']);?>">
Name: <input type="text" name="name" value="<?php echo isset($name) ? htmlspecialchars($name) : '';?>">
<span class="error">* <?php echo isset($nameErr) ? $nameErr : '';?></span>
<br><br>
E-mail: <input type="text" name="email" value="<?php echo isset($email) ? htmlspecialchars($email) : '';?>">
<span class="error">* <?php echo isset($emailErr) ? $emailErr : '';?></span>
<br><br>
Website: <input type="text" name="website" value="<?php echo isset($website) ? htmlspecialchars($website) : '';?>">
<span class="error"><?php echo isset($websiteErr) ? $websiteErr : '';?></span>
<br><br>
Comment: <textarea name="comment" rows="5" cols="40"><?php echo isset($comment) ? htmlspecialchars($comment) : '';?></textarea>
<br><br>
Gender:
<input type="radio" name="gender" <?php if (isset($gender) && $gender=="female") echo "checked";?> value="female">Female
<input type="radio" name="gender" <?php if (isset($gender) && $gender=="male") echo "checked";?> value="male">Male
<input type="radio" name="gender" <?php if (isset($gender) && $gender=="other") echo "checked";?> value="other">Other
<span class="error">* <?php echo isset($genderErr) ? $genderErr : '';?></span>
<br><br>
<input type="submit" name="submit" value="Submit">
</form>

Validation Rules:

FieldValidation Rules
NameRequired. Must only contain letters and whitespace.
E-mailRequired. Must contain a valid email address format.
WebsiteOptional. If present, it must contain a valid URL format.
CommentOptional. Multi-line input field.
GenderRequired. Must select one option.

The form’s action attribute specifies where to send the form data when submitted.

<form method="post" action="<?php echo htmlspecialchars($_SERVER['PHP_SELF']);?>">
  • $_SERVER['PHP_SELF'] refers to the current script file. Submitting the form reloads the same page, allowing PHP code within it to process the data and display errors.
  • htmlspecialchars() is crucial here. It converts special HTML characters (like < and >) into their HTML entity equivalents (&lt; and &gt;). This prevents Cross-Site Scripting (XSS) attacks where an attacker might inject malicious code into the URL, manipulating the action attribute if htmlspecialchars() wasn’t used.

Example of XSS Exploit (Without htmlspecialchars()):

If the action was just <?php echo $_SERVER['PHP_SELF'];?>, an attacker could craft a URL like:

http://example.com/form.php/"><script>alert('hacked')</script>

This could render the form tag as:

<form method="post" action="form.php/"><script>alert('hacked')</script>">

The injected script would then execute in the user’s browser. Using htmlspecialchars() prevents this by encoding the malicious characters.

  • Sanitization: Cleaning or filtering input data. Examples: trim() removes whitespace from the beginning/end; htmlspecialchars() escapes HTML for safe output. Sanitization makes data safe to handle or display.
  • Validation: Checking if data conforms to expected rules. Examples: Is an email address in a valid format? Is a required field non-empty? Is a number within a specific range?

You typically sanitize input before validating it, and you must escape output before displaying it in HTML.

3. trim() and stripslashes() (Historical Note)

Section titled “3. trim() and stripslashes() (Historical Note)”
  • trim(): Useful for removing accidental leading/trailing whitespace from user input.
  • stripslashes(): Removed backslashes added by the older, deprecated magic_quotes_gpc feature. You generally do not need stripslashes() in modern PHP (PHP 5.4+), as magic quotes have been removed. Using it unnecessarily might corrupt valid data containing backslashes.

Let’s build the PHP code to handle the form submission and validation.

<?php
// Define variables and set to empty values
$nameErr = $emailErr = $genderErr = $websiteErr = "";
$name = $email = $gender = $comment = $website = "";
// Check if the form was submitted using POST
if ($_SERVER["REQUEST_METHOD"] == "POST") {
// --- Name Validation ---
if (empty($_POST["name"])) {
$nameErr = "Name is required";
} else {
$name = sanitize_input($_POST["name"]);
// Check if name only contains letters and whitespace
if (!preg_match("/^[a-zA-Z-' ]*$/", $name)) {
$nameErr = "Only letters and white space allowed";
}
}
// --- Email Validation ---
if (empty($_POST["email"])) {
$emailErr = "Email is required";
} else {
$email = sanitize_input($_POST["email"]);
// Check if e-mail address is well-formed using PHP's built-in filter
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$emailErr = "Invalid email format";
}
}
// --- Website Validation (Optional) ---
if (empty($_POST["website"])) {
$website = "";
} else {
$website = sanitize_input($_POST["website"]);
// Check if URL syntax is valid (allows schemes like http, https)
// FILTER_VALIDATE_URL requires a scheme by default
if (!preg_match("/\b(?:(?:https?|ftp):\/\/|www\.)[-a-z0-9+&@#\/%?=~_|!:,.;]*[-a-z0-9+&@#\/%=~_|]/i", $website)) {
$websiteErr = "Invalid URL format";
} else if (!filter_var($website, FILTER_VALIDATE_URL)) {
// Use filter_var as a secondary check for general structure
// This check might be too strict depending on requirements; regex often more practical
// $websiteErr = "Invalid URL";
}
}
// --- Comment Sanitization (Optional) ---
if (empty($_POST["comment"])) {
$comment = "";
} else {
$comment = sanitize_input($_POST["comment"]);
// No specific validation rule here, just sanitization
}
// --- Gender Validation ---
if (empty($_POST["gender"])) {
$genderErr = "Gender is required";
} else {
$gender = sanitize_input($_POST["gender"]);
// Optional: Check if the value is one of the expected ones
$allowed_genders = ['female', 'male', 'other'];
if (!in_array($gender, $allowed_genders)) {
$genderErr = "Invalid gender selection";
$gender = ""; // Reset if invalid
}
}
// If all validations passed, you can process the data (e.g., save to database)
if (empty($nameErr) && empty($emailErr) && empty($websiteErr) && empty($genderErr)) {
// Process the data...
echo "<h2>Form Submitted Successfully:</h2>";
echo "Name: " . htmlspecialchars($name) . "<br>";
echo "Email: " . htmlspecialchars($email) . "<br>";
echo "Website: " . htmlspecialchars($website) . "<br>";
echo "Comment: " . nl2br(htmlspecialchars($comment)) . "<br>"; // Use nl2br for line breaks
echo "Gender: " . htmlspecialchars($gender) . "<br>";
// Clear form variables after successful submission if desired
// $name = $email = $gender = $comment = $website = "";
exit; // Stop script execution after successful processing if redirecting or done
}
}
// Basic sanitization function (trim whitespace)
// Note: No stripslashes() needed in modern PHP
function sanitize_input($data) {
$data = trim($data);
// $data = stripslashes($data); // Deprecated - Don't use unless dealing with legacy magic_quotes
// htmlspecialchars should be used on OUTPUT, not generally on input storage
return $data;
}
?>
<!-- HTML Form (as shown above) goes here -->
<!-- It uses the PHP variables $name, $email, etc. to repopulate fields -->
<!-- And $nameErr, $emailErr, etc. to display error messages -->
  1. Initialization: Variables for storing form data ($name, $email, etc.) and corresponding error messages ($nameErr, $emailErr, etc.) are initialized to empty strings.
  2. Check Request Method: if ($_SERVER["REQUEST_METHOD"] == "POST") ensures the validation code only runs when the form is submitted via POST.
  3. Sanitize Input: The sanitize_input() function (here, just using trim()) cleans the raw input.
  4. Validate Required Fields: empty() checks if required fields (Name, Email, Gender) are submitted.
  5. Validate Format (Name): preg_match() checks if the name contains only allowed characters (letters, apostrophe, dash, space).
  6. Validate Format (Email): filter_var($email, FILTER_VALIDATE_EMAIL) uses PHP’s built-in filter, a reliable way to check email format.
  7. Validate Format (Website): preg_match() provides a more flexible URL pattern check. filter_var($website, FILTER_VALIDATE_URL) can also be used but might be stricter (e.g., requiring http://). Choose the method that best fits your needs.
  8. Process Data: If all error variables remain empty after validation, the data is considered valid and can be processed (e.g., saved to a database, sent via email). Remember to use htmlspecialchars() when displaying this data back in HTML.
  9. Display Errors & Repopulate Form: The HTML form uses the PHP error variables ($nameErr, etc.) to display messages next to the relevant fields. It also uses the data variables ($name, $email, etc., wrapped in htmlspecialchars() for safety) in the value attributes (or textarea content) to repopulate the form with the user’s previous input if validation fails.
  • More Robust Sanitization/Validation: Use libraries like laminas-filter, laminas-validator, or Respect\Validation for more complex scenarios.
  • CSRF Protection: Implement Cross-Site Request Forgery tokens to protect against CSRF attacks.
  • Centralized Validation Logic: For larger forms, consider creating validation classes or functions for better organization.