PHP Forms & Data Processing
CMU529: Advanced Web Development - Session 5
Birmingham Newman University
Lecturer: James Williams
Advanced form handling and validation techniques
3-hour session • 27 slides • 2 interactive tasks
Session Timeline:
- 10 min: Registration & waiting
- 20 min: Opening slides
- 45 min: Task 1
- 15 min: Break/Catch up
- 20 min: Secondary slides
- 45 min: Task 2
- Remaining: Self-study
Learning Objectives
- Master advanced form handling techniques
- Implement comprehensive input validation
- Create secure form processing systems
- Handle file uploads safely
- Build user registration and login systems
- Implement form security best practices
Form Processing Overview
Form Processing Flow
1. User submits form
2. Browser sends data to server
3. PHP receives data via $_POST/$_GET
4. Validate and sanitize input
5. Process data (database, email, etc.)
6. Send response back to user
- Forms are the primary way users interact with web applications
- Proper validation prevents security vulnerabilities
- User-friendly error messages improve experience
- CSRF protection prevents unauthorized form submissions
HTML Form Structure
Complete Form Example:
<form method="POST" action="process.php" enctype="multipart/form-data">
<div class="form-group">
<label for="username">Username:</label>
<input type="text" name="username" id="username" required>
</div>
<div class="form-group">
<label for="email">Email:</label>
<input type="email" name="email" id="email" required>
</div>
<div class="form-group">
<label for="password">Password:</label>
<input type="password" name="password" id="password" required>
</div>
<div class="form-group">
<label for="avatar">Profile Picture:</label>
<input type="file" name="avatar" id="avatar" accept="image/*">
</div>
<button type="submit">Register</button>
</form>
Basic Form Processing
Basic Processing (process.php):
<?php
// Check if form was submitted
if ($_SERVER["REQUEST_METHOD"] == "POST") {
// Get form data
$username = $_POST["username"];
$email = $_POST["email"];
$password = $_POST["password"];
// Basic validation
if (empty($username) || empty($email) || empty($password)) {
$error = "All fields are required";
} else {
// Process the data
echo "Username: " . htmlspecialchars($username) . "<br>";
echo "Email: " . htmlspecialchars($email) . "<br>";
echo "Registration successful!";
}
}
?>
Input Validation Functions
Validation Functions:
function validateEmail($email) {
return filter_var($email, FILTER_VALIDATE_EMAIL);
}
function validateUsername($username) {
// Username: 3-20 characters, alphanumeric and underscore
return preg_match("/^[a-zA-Z0-9_]{3,20}$/", $username);
}
function validatePassword($password) {
// Password: minimum 8 characters, at least one letter and number
return strlen($password) >= 8 &&
preg_match("/[a-zA-Z]/", $password) &&
preg_match("/[0-9]/", $password);
}
function sanitizeInput($input) {
return htmlspecialchars(trim($input), ENT_QUOTES, 'UTF-8');
}
Advanced Form Validation
Comprehensive Validation:
function validateRegistration($data) {
$errors = [];
// Username validation
if (empty($data["username"])) {
$errors["username"] = "Username is required";
} elseif (!validateUsername($data["username"])) {
$errors["username"] = "Username must be 3-20 characters";
}
// Email validation
if (empty($data["email"])) {
$errors["email"] = "Email is required";
} elseif (!validateEmail($data["email"])) {
$errors["email"] = "Invalid email format";
}
// Password validation
if (empty($data["password"])) {
$errors["password"] = "Password is required";
} elseif (!validatePassword($data["password"])) {
$errors["password"] = "Password must be at least 8 characters";
}
return $errors;
}
File Upload Handling
File Upload Processing:
function handleFileUpload($file) {
$errors = [];
$uploadDir = "uploads/";
// Check if file was uploaded
if ($file["error"] !== UPLOAD_ERR_OK) {
$errors[] = "File upload failed";
return $errors;
}
// Validate file type
$allowedTypes = ["image/jpeg", "image/png", "image/gif"];
if (!in_array($file["type"], $allowedTypes)) {
$errors[] = "Invalid file type";
}
// Validate file size (5MB max)
if ($file["size"] > 5 * 1024 * 1024) {
$errors[] = "File too large (max 5MB)";
}
// Generate unique filename
$extension = pathinfo($file["name"], PATHINFO_EXTENSION);
$filename = uniqid() . "." . $extension;
$filepath = $uploadDir . $filename;
// Move uploaded file
if (!move_uploaded_file($file["tmp_name"], $filepath)) {
$errors[] = "Failed to save file";
}
return $errors;
}
CSRF Protection
CSRF Token Implementation:
// Generate CSRF token
function generateCSRFToken() {
if (empty($_SESSION["csrf_token"])) {
$_SESSION["csrf_token"] = bin2hex(random_bytes(32));
}
return $_SESSION["csrf_token"];
}
// Verify CSRF token
function verifyCSRFToken($token) {
return isset($_SESSION["csrf_token"]) &&
hash_equals($_SESSION["csrf_token"], $token);
}
// Add token to form
<form method="POST" action="process.php">
<input type="hidden" name="csrf_token" value="<?php echo generateCSRFToken(); ?>">
<!-- form fields -->
</form>
// Verify in processing
if (!verifyCSRFToken($_POST["csrf_token"])) {
die("CSRF token validation failed");
}
User Registration System
Registration Processing:
function registerUser($data) {
// Validate input
$errors = validateRegistration($data);
if (!empty($errors)) {
return ["success" => false, "errors" => $errors];
}
// Check if user already exists
if (userExists($data["email"])) {
return ["success" => false, "errors" => ["email" => "Email already registered"]];
}
// Hash password
$hashedPassword = password_hash($data["password"], PASSWORD_DEFAULT);
// Create user
$userId = createUser([
"username" => $data["username"],
"email" => $data["email"],
"password" => $hashedPassword
]);
return ["success" => true, "user_id" => $userId];
}
User Login System
Login Processing:
function loginUser($email, $password) {
// Validate input
if (empty($email) || empty($password)) {
return ["success" => false, "error" => "Email and password required"];
}
// Get user from database
$user = getUserByEmail($email);
if (!$user) {
return ["success" => false, "error" => "Invalid credentials"];
}
// Verify password
if (!password_verify($password, $user["password"])) {
return ["success" => false, "error" => "Invalid credentials"];
}
// Start session and store user data
session_start();
$_SESSION["user_id"] = $user["id"];
$_SESSION["username"] = $user["username"];
$_SESSION["logged_in"] = true;
return ["success" => true, "user" => $user];
}
Form Error Handling
Error Display System:
// Display errors function
function displayErrors($errors, $field) {
if (isset($errors[$field])) {
return "<span class='error'>" . htmlspecialchars($errors[$field]) . "</span>";
}
return "";
}
// Form with error display
<form method="POST" action="register.php">
<div class="form-group">
<label for="username">Username:</label>
<input type="text" name="username" id="username"
value="<?php echo isset($_POST['username']) ? htmlspecialchars($_POST['username']) : ''; ?>">
<?php echo displayErrors($errors, 'username'); ?>
</div>
<div class="form-group">
<label for="email">Email:</label>
<input type="email" name="email" id="email"
value="<?php echo isset($_POST['email']) ? htmlspecialchars($_POST['email']) : ''; ?>">
<?php echo displayErrors($errors, 'email'); ?>
</div>
</form>
E-commerce Form Examples
Product Search Form:
<form method="GET" action="search.php">
<input type="text" name="q" placeholder="Search products..."
value="<?php echo isset($_GET['q']) ? htmlspecialchars($_GET['q']) : ''; ?>">
<select name="category">
<option value="">All Categories</option>
<option value="electronics">Electronics</option>
<option value="clothing">Clothing</option>
<option value="books">Books</option>
</select>
<button type="submit">Search</button>
</form>
Contact Form:
<form method="POST" action="contact.php">
<input type="text" name="name" placeholder="Your Name" required>
<input type="email" name="email" placeholder="Your Email" required>
<textarea name="message" placeholder="Your Message" required></textarea>
<button type="submit">Send Message</button>
</form>
Task 1: Advanced Form Processing
Instructions:
- Create a comprehensive registration system with:
- User registration form with validation
- File upload for profile pictures
- CSRF protection implementation
- Password strength validation
- Email format validation
- Error handling and display
- Implement login functionality
- Add session management
- Create password reset functionality
- Test all security measures
Time: 45 minutes
This task will help you master advanced form processing techniques
Break Time
15 Minutes
Take a break, ask questions, or catch up on the previous task.
Next: Secondary slides and Task 2
Form Security Best Practices
- Input Validation: Validate all inputs on server-side
- Output Escaping: Escape all output with htmlspecialchars()
- CSRF Protection: Use tokens for all forms
- Password Hashing: Never store plain text passwords
- File Upload Security: Validate file types and sizes
- Rate Limiting: Prevent form spam and attacks
Security Checklist:
✓ Validate all input data
✓ Escape all output data
✓ Use CSRF tokens
✓ Hash passwords with password_hash()
✓ Validate file uploads
✓ Use HTTPS in production
✓ Implement rate limiting
✓ Log security events
✓ Keep PHP and dependencies updated
AJAX Form Submission
JavaScript AJAX Example:
document.getElementById('registerForm').addEventListener('submit', function(e) {
e.preventDefault();
const formData = new FormData(this);
fetch('register.php', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => {
if (data.success) {
alert('Registration successful!');
} else {
displayErrors(data.errors);
}
})
.catch(error => {
console.error('Error:', error);
});
});
PHP Response (register.php):
header('Content-Type: application/json');
echo json_encode($result);
Form Validation with JavaScript
Client-side Validation:
function validateForm() {
let isValid = true;
const errors = {};
// Username validation
const username = document.getElementById('username').value;
if (username.length < 3 || username.length > 20) {
errors.username = 'Username must be 3-20 characters';
isValid = false;
}
// Email validation
const email = document.getElementById('email').value;
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(email)) {
errors.email = 'Invalid email format';
isValid = false;
}
// Password validation
const password = document.getElementById('password').value;
if (password.length < 8) {
errors.password = 'Password must be at least 8 characters';
isValid = false;
}
return { isValid, errors };
}
Database Integration
Database Functions:
function createUser($userData) {
global $pdo;
$sql = "INSERT INTO users (username, email, password, created_at) VALUES (?, ?, ?, NOW())";
$stmt = $pdo->prepare($sql);
try {
$stmt->execute([
$userData['username'],
$userData['email'],
$userData['password']
]);
return $pdo->lastInsertId();
} catch (PDOException $e) {
error_log("Database error: " . $e->getMessage());
return false;
}
}
function getUserByEmail($email) {
global $pdo;
$sql = "SELECT * FROM users WHERE email = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([$email]);
return $stmt->fetch(PDO::FETCH_ASSOC);
}
Email Integration
Email Functions:
function sendWelcomeEmail($email, $username) {
$to = $email;
$subject = "Welcome to Our E-commerce Site";
$message = "Hello $username,\n\nWelcome to our store!";
$headers = "From: noreply@example.com";
return mail($to, $subject, $message, $headers);
}
function sendPasswordReset($email, $token) {
$resetLink = "https://example.com/reset.php?token=" . $token;
$to = $email;
$subject = "Password Reset Request";
$message = "Click the following link to reset your password:\n$resetLink";
$headers = "From: noreply@example.com";
return mail($to, $subject, $message, $headers);
}
function sendOrderConfirmation($email, $orderDetails) {
$to = $email;
$subject = "Order Confirmation";
$message = "Thank you for your order!\n\nOrder ID: " . $orderDetails['id'];
$headers = "From: orders@example.com";
return mail($to, $subject, $message, $headers);
}
Form Analytics and Tracking
- Conversion Tracking: Monitor form completion rates
- Error Tracking: Log validation errors for improvement
- User Behavior: Track form abandonment points
- Performance Monitoring: Monitor form submission times
- A/B Testing: Test different form layouts
Analytics Implementation:
function logFormSubmission($formType, $success, $errors = []) {
$logData = [
'timestamp' => date('Y-m-d H:i:s'),
'form_type' => $formType,
'success' => $success,
'errors' => json_encode($errors),
'ip_address' => $_SERVER['REMOTE_ADDR'],
'user_agent' => $_SERVER['HTTP_USER_AGENT']
];
// Log to database or file
logToDatabase('form_submissions', $logData);
}
Task 2: Complete E-commerce Form System
Instructions:
- Build a complete e-commerce form system with:
- User registration and login forms
- Product search and filtering forms
- Contact and support forms
- Shopping cart and checkout forms
- Product review and rating forms
- Implement comprehensive validation
- Add AJAX form submission
- Include email notifications
- Add form analytics tracking
- Ensure all security measures are in place
Time: 45 minutes
This task will help you build a complete e-commerce form processing system
Session Summary
- Advanced form processing requires comprehensive validation
- Security measures are essential for all forms
- File uploads require careful validation and handling
- CSRF protection prevents unauthorized form submissions
- AJAX enhances user experience for form submissions
- Database integration enables persistent data storage
- Email integration provides user communication
- Analytics help improve form performance
Next Session:
MySQL Database Design - Database fundamentals and e-commerce schema