← Back to Module

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:

  1. 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
  2. Implement login functionality
  3. Add session management
  4. Create password reset functionality
  5. 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:

  1. 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
  2. Implement comprehensive validation
  3. Add AJAX form submission
  4. Include email notifications
  5. Add form analytics tracking
  6. 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