Table of Contents
PHP Forms and User Input
Forms are essential for collecting user input in web applications. PHP provides powerful tools to handle form data securely and efficiently.
HTML Form Basics
Create forms that send data to PHP scripts:
<!-- Basic HTML form -->
<form action="process.php" method="POST">
<label for="name">Name:</label>
<input type="text" id="name" name="name" required>
<label for="email">Email:</label>
<input type="email" id="email" name="email" required>
<label for="age">Age:</label>
<input type="number" id="age" name="age" min="1" max="120">
<button type="submit">Submit</button>
</form>
GET vs POST Methods
Understanding when to use each method:
<?php
// GET method - data visible in URL
// Good for: search forms, filtering, bookmarkable pages
if ($_SERVER["REQUEST_METHOD"] == "GET") {
$searchTerm = $_GET["search"] ?? "";
echo "Searching for: " . htmlspecialchars($searchTerm);
}
?>
<form action="" method="GET">
<input type="text" name="search" placeholder="Search...">
<button type="submit">Search</button>
</form>
<?php
// POST method - data hidden from URL
// Good for: login forms, sensitive data, file uploads
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$username = $_POST["username"] ?? "";
$password = $_POST["password"] ?? "";
// Process login (never echo passwords!)
if (!empty($username) && !empty($password)) {
// Authenticate user
echo "Processing login for: " . htmlspecialchars($username);
}
}
?>
<form action="" method="POST">
<input type="text" name="username" placeholder="Username" required>
<input type="password" name="password" placeholder="Password" required>
<button type="submit">Login</button>
</form>
Accessing Form Data
PHP superglobals for form data:
<?php
// $_POST - for POST method data
if (isset($_POST["submit"])) {
$name = $_POST["name"];
$email = $_POST["email"];
$message = $_POST["message"];
}
// $_GET - for GET method data
$page = $_GET["page"] ?? 1;
$category = $_GET["category"] ?? "all";
// $_REQUEST - contains both GET and POST (not recommended)
$data = $_REQUEST["data"]; // Avoid using this
// Check if form was submitted
if ($_SERVER["REQUEST_METHOD"] == "POST") {
// Process POST data
} elseif ($_SERVER["REQUEST_METHOD"] == "GET") {
// Process GET data
}
?>
Form Validation
Always validate and sanitize user input:
<?php
$errors = [];
$name = $email = $age = "";
if ($_SERVER["REQUEST_METHOD"] == "POST") {
// Validate name
if (empty($_POST["name"])) {
$errors["name"] = "Name is required";
} else {
$name = trim($_POST["name"]);
if (strlen($name) < 2) {
$errors["name"] = "Name must be at least 2 characters";
}
}
// Validate email
if (empty($_POST["email"])) {
$errors["email"] = "Email is required";
} else {
$email = trim($_POST["email"]);
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$errors["email"] = "Invalid email format";
}
}
// Validate age
if (!empty($_POST["age"])) {
$age = (int)$_POST["age"];
if ($age < 1 || $age > 120) {
$errors["age"] = "Age must be between 1 and 120";
}
}
// If no errors, process the form
if (empty($errors)) {
echo "Form submitted successfully!";
// Save to database, send email, etc.
}
}
?>
<form method="POST">
<div>
<label for="name">Name:</label>
<input type="text" id="name" name="name" value="<?= htmlspecialchars($name) ?>">
<?php if (isset($errors["name"])): ?>
<span class="error"><?= $errors["name"] ?></span>
<?php endif; ?>
</div>
<div>
<label for="email">Email:</label>
<input type="email" id="email" name="email" value="<?= htmlspecialchars($email) ?>">
<?php if (isset($errors["email"])): ?>
<span class="error"><?= $errors["email"] ?></span>
<?php endif; ?>
</div>
<button type="submit">Submit</button>
</form>
Input Sanitization
Clean user input to prevent security issues:
<?php
function sanitizeInput($data) {
$data = trim($data); // Remove whitespace
$data = stripslashes($data); // Remove backslashes
$data = htmlspecialchars($data); // Convert special chars
return $data;
}
// Sanitize all POST data
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$name = sanitizeInput($_POST["name"]);
$email = sanitizeInput($_POST["email"]);
$message = sanitizeInput($_POST["message"]);
}
// Filter functions for specific data types
$email = filter_var($_POST["email"], FILTER_SANITIZE_EMAIL);
$url = filter_var($_POST["website"], FILTER_SANITIZE_URL);
$int = filter_var($_POST["age"], FILTER_SANITIZE_NUMBER_INT);
// Validation filters
$isValidEmail = filter_var($email, FILTER_VALIDATE_EMAIL);
$isValidUrl = filter_var($url, FILTER_VALIDATE_URL);
$isValidInt = filter_var($int, FILTER_VALIDATE_INT);
?>
Different Input Types
Handle various HTML5 input types:
<form method="POST" enctype="multipart/form-data">
<!-- Text inputs -->
<input type="text" name="username" placeholder="Username">
<input type="email" name="email" placeholder="Email">
<input type="password" name="password" placeholder="Password">
<input type="url" name="website" placeholder="Website">
<input type="tel" name="phone" placeholder="Phone">
<!-- Number inputs -->
<input type="number" name="age" min="1" max="120">
<input type="range" name="rating" min="1" max="10">
<!-- Date inputs -->
<input type="date" name="birthdate">
<input type="time" name="appointment">
<input type="datetime-local" name="event">
<!-- Selection inputs -->
<select name="country">
<option value="">Select Country</option>
<option value="us">United States</option>
<option value="ca">Canada</option>
<option value="uk">United Kingdom</option>
</select>
<!-- Checkboxes -->
<input type="checkbox" name="newsletter" value="1"> Subscribe to newsletter
<input type="checkbox" name="hobbies[]" value="reading"> Reading
<input type="checkbox" name="hobbies[]" value="sports"> Sports
<input type="checkbox" name="hobbies[]" value="music"> Music
<!-- Radio buttons -->
<input type="radio" name="gender" value="male"> Male
<input type="radio" name="gender" value="female"> Female
<input type="radio" name="gender" value="other"> Other
<!-- Textarea -->
<textarea name="comments" rows="4" cols="50" placeholder="Comments"></textarea>
<!-- File upload -->
<input type="file" name="avatar" accept="image/*">
<button type="submit">Submit</button>
</form>
<?php
if ($_SERVER["REQUEST_METHOD"] == "POST") {
// Handle different input types
$username = $_POST["username"] ?? "";
$age = (int)($_POST["age"] ?? 0);
$birthdate = $_POST["birthdate"] ?? "";
$country = $_POST["country"] ?? "";
$newsletter = isset($_POST["newsletter"]);
$hobbies = $_POST["hobbies"] ?? [];
$gender = $_POST["gender"] ?? "";
$comments = $_POST["comments"] ?? "";
echo "Username: " . htmlspecialchars($username) . "<br>";
echo "Age: " . $age . "<br>";
echo "Newsletter: " . ($newsletter ? "Yes" : "No") . "<br>";
echo "Hobbies: " . implode(", ", $hobbies) . "<br>";
}
?>
File Upload Handling
Handle file uploads securely:
<?php
if ($_SERVER["REQUEST_METHOD"] == "POST" && isset($_FILES["avatar"])) {
$file = $_FILES["avatar"];
// Check for upload errors
if ($file["error"] == UPLOAD_ERR_OK) {
$fileName = $file["name"];
$fileSize = $file["size"];
$fileTmp = $file["tmp_name"];
$fileType = $file["type"];
// Validate file
$allowedTypes = ["image/jpeg", "image/png", "image/gif"];
$maxSize = 2 * 1024 * 1024; // 2MB
if (!in_array($fileType, $allowedTypes)) {
echo "Error: Only JPEG, PNG, and GIF files are allowed.";
} elseif ($fileSize > $maxSize) {
echo "Error: File size must be less than 2MB.";
} else {
// Generate unique filename
$extension = pathinfo($fileName, PATHINFO_EXTENSION);
$newFileName = uniqid() . "." . $extension;
$uploadPath = "uploads/" . $newFileName;
// Move uploaded file
if (move_uploaded_file($fileTmp, $uploadPath)) {
echo "File uploaded successfully: " . $newFileName;
} else {
echo "Error: Failed to upload file.";
}
}
} else {
echo "Error: " . $file["error"];
}
}
?>
<form method="POST" enctype="multipart/form-data">
<input type="file" name="avatar" accept="image/*" required>
<button type="submit">Upload</button>
</form>
Form Security
Protect against common attacks:
<?php
session_start();
// CSRF Protection
function generateCSRFToken() {
if (!isset($_SESSION["csrf_token"])) {
$_SESSION["csrf_token"] = bin2hex(random_bytes(32));
}
return $_SESSION["csrf_token"];
}
function validateCSRFToken($token) {
return isset($_SESSION["csrf_token"]) &&
hash_equals($_SESSION["csrf_token"], $token);
}
// Process form with CSRF protection
if ($_SERVER["REQUEST_METHOD"] == "POST") {
if (!validateCSRFToken($_POST["csrf_token"] ?? "")) {
die("CSRF token validation failed");
}
// Process form data...
}
?>
<form method="POST">
<input type="hidden" name="csrf_token" value="<?= generateCSRFToken() ?>">
<input type="text" name="username" required>
<input type="password" name="password" required>
<button type="submit">Login</button>
</form>
Practical Example: Contact Form
<?php
$errors = [];
$success = false;
$name = $email = $subject = $message = "";
if ($_SERVER["REQUEST_METHOD"] == "POST") {
// Validate and sanitize input
$name = trim($_POST["name"] ?? "");
$email = trim($_POST["email"] ?? "");
$subject = trim($_POST["subject"] ?? "");
$message = trim($_POST["message"] ?? "");
// Validation
if (empty($name)) {
$errors["name"] = "Name is required";
}
if (empty($email)) {
$errors["email"] = "Email is required";
} elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$errors["email"] = "Invalid email format";
}
if (empty($subject)) {
$errors["subject"] = "Subject is required";
}
if (empty($message)) {
$errors["message"] = "Message is required";
} elseif (strlen($message) < 10) {
$errors["message"] = "Message must be at least 10 characters";
}
// If no errors, send email
if (empty($errors)) {
$to = "admin@example.com";
$headers = "From: " . $email . "
";
$headers .= "Reply-To: " . $email . "
";
$headers .= "Content-Type: text/html; charset=UTF-8
";
$emailBody = "<h3>Contact Form Submission</h3>";
$emailBody .= "<p><strong>Name:</strong> " . htmlspecialchars($name) . "</p>";
$emailBody .= "<p><strong>Email:</strong> " . htmlspecialchars($email) . "</p>";
$emailBody .= "<p><strong>Subject:</strong> " . htmlspecialchars($subject) . "</p>";
$emailBody .= "<p><strong>Message:</strong></p>";
$emailBody .= "<p>" . nl2br(htmlspecialchars($message)) . "</p>";
if (mail($to, $subject, $emailBody, $headers)) {
$success = true;
$name = $email = $subject = $message = ""; // Clear form
} else {
$errors["general"] = "Failed to send message. Please try again.";
}
}
}
?>
<!DOCTYPE html>
<html>
<head>
<title>Contact Form</title>
<style>
.error { color: red; font-size: 0.9em; }
.success { color: green; padding: 10px; background: #e8f5e8; }
.form-group { margin-bottom: 15px; }
label { display: block; margin-bottom: 5px; }
input, textarea, select { width: 100%; padding: 8px; }
</style>
</head>
<body>
<h1>Contact Us</h1>
<?php if ($success): ?>
<div class="success">Thank you! Your message has been sent.</div>
<?php endif; ?>
<?php if (isset($errors["general"])): ?>
<div class="error"><?= $errors["general"] ?></div>
<?php endif; ?>
<form method="POST">
<div class="form-group">
<label for="name">Name:</label>
<input type="text" id="name" name="name" value="<?= htmlspecialchars($name) ?>">
<?php if (isset($errors["name"])): ?>
<div class="error"><?= $errors["name"] ?></div>
<?php endif; ?>
</div>
<div class="form-group">
<label for="email">Email:</label>
<input type="email" id="email" name="email" value="<?= htmlspecialchars($email) ?>">
<?php if (isset($errors["email"])): ?>
<div class="error"><?= $errors["email"] ?></div>
<?php endif; ?>
</div>
<div class="form-group">
<label for="subject">Subject:</label>
<input type="text" id="subject" name="subject" value="<?= htmlspecialchars($subject) ?>">
<?php if (isset($errors["subject"])): ?>
<div class="error"><?= $errors["subject"] ?></div>
<?php endif; ?>
</div>
<div class="form-group">
<label for="message">Message:</label>
<textarea id="message" name="message" rows="5"><?= htmlspecialchars($message) ?></textarea>
<?php if (isset($errors["message"])): ?>
<div class="error"><?= $errors["message"] ?></div>
<?php endif; ?>
</div>
<button type="submit">Send Message</button>
</form>
</body>
</html>
Practice Exercise
Create a user registration form that:
- Collects username, email, password, and confirm password
- Validates all fields with appropriate error messages
- Checks if username/email already exists
- Includes CSRF protection
- Handles file upload for profile picture
Key Takeaways
- Always validate and sanitize user input
- Use POST for sensitive data, GET for searches
- Implement CSRF protection for security
- Handle file uploads carefully with validation
- Provide clear error messages and user feedback