HTML forms are the universal bridge between website visitors and backend web servers. Whether a user is logging into a student portal, submitting an examination assignment, or leaving a blog comment, PHP processes form data seamlessly. However, handling form data properly requires understanding the critical architectural differences between GET and POST methods, robust server-side data validation, and bulletproof sanitization against Cross-Site Scripting (XSS) attacks.
| Feature | GET Method ($_GET) |
POST Method ($_POST) |
|---|---|---|
| Data Transmission | Appended visibly to the URL as query parameters (e.g. ?query=php&page=1). |
Sent invisibly inside the HTTP message body. |
| Data Visibility & History | Visible in browser address bar, server access logs, and browser history. | Completely hidden from browser address bar and URL history. |
| Payload Size Limit | Strictly restricted by browser URL limits (~2,048 characters). | Virtually unlimited (governed by post_max_size in php.ini). |
| File Upload Support | Cannot be used for binary file uploads. | Required for file uploads (with enctype="multipart/form-data"). |
| Bookmarkable / Cacheable | Yes, query results can be bookmarked and cached by Google. | No, browser prompts "Confirm Form Resubmission" on refresh. |
| Best Use Cases | Search bars, pagination filters, read-only data queries. | Login forms, registration, payments, database updates. |
Here is a production-grade self-processing PHP form featuring server-side validation and sanitization:
<?php
$name = $email = $course = "";
$nameErr = $emailErr = "";
$successMsg = "";
// Check if form was submitted via HTTP POST
if ($_SERVER["REQUEST_METHOD"] === "POST") {
// 1. Validate & Sanitize Name
if (empty($_POST["full_name"])) {
$nameErr = "Student name is required.";
} else {
// htmlspecialchars prevents XSS; trim removes extra spaces
$name = htmlspecialchars(trim($_POST["full_name"]));
if (!preg_match("/^[a-zA-Z-' ]*$/", $name)) {
$nameErr = "Only letters and spaces allowed in name.";
}
}
// 2. Validate & Sanitize Email
if (empty($_POST["email"])) {
$emailErr = "Email address is required.";
} else {
$email = filter_var(trim($_POST["email"]), FILTER_SANITIZE_EMAIL);
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$emailErr = "Invalid email format entered.";
}
}
// 3. Process If No Validation Errors
if (empty($nameErr) && empty($emailErr)) {
$course = htmlspecialchars($_POST["course"]);
$successMsg = "Registration Successful! Welcome, $name ($course).";
// In a live app, insert securely into database via PDO here!
}
}
?>
<!-- HTML Form -->
<?php if ($successMsg): ?>
<div class="alert alert-success"><?= $successMsg ?></div>
<?php endif; ?>
<form method="POST" action="<?= htmlspecialchars($_SERVER["PHP_SELF"]); ?>">
<div class="form-group">
<label>Full Name:</label>
<input type="text" name="full_name" value="<?= $name ?>" class="form-control">
<span style="color:red;"><?= $nameErr ?></span>
</div>
<div class="form-group">
<label>Email Address:</label>
<input type="email" name="email" value="<?= $email ?>" class="form-control">
<span style="color:red;"><?= $emailErr ?></span>
</div>
<div class="form-group">
<label>Select Degree Course:</label>
<select name="course" class="form-control">
<option value="BCA">BCA (Computer Applications)</option>
<option value="B.Tech CS">B.Tech Computer Science</option>
<option value="BSc IT">BSc Information Technology</option>
</select>
</div>
<button type="submit" class="btn btn-primary">Submit Registration</button>
</form>
High-Frequency Exam Question:
Q: Why is $_REQUEST discouraged in production form handling?
A: $_REQUEST merges data from $_GET, $_POST, and $_COOKIE. If a form was meant to be submitted via POST, an attacker could bypass form security by sending malicious parameters in a GET query string or cookie. Explicitly using $_POST enforces strict HTTP method validation.
Exercise 25.1: Create a contact form with fields for Name, Email, Subject, and Message. Ensure that all fields are required and sanitized.
Exercise 25.2: Implement a simple CSRF token mechanism using bin2hex(random_bytes(32)) stored in $_SESSION['csrf_token'].