Share:

Forms

intermediate

Part of PHP Web Features

Theory

Processing HTML forms is one of PHP's core strengths. PHP makes it easy to collect, validate, and process user input from web forms.

GET vs POST Method

GET appends form data to the URL as query parameters:

http://example.com/search.php?q=php&category=books
  • Data visible in URL
  • Limited to ~2000 characters
  • Can be bookmarked
  • Used for searches, filters, read-only operations

POST sends data in the HTTP request body:

POST /login.php
Content-Type: application/x-www-form-urlencoded

username=alice&password=secret123
  • Data not visible in URL
  • No size limit
  • Cannot be bookmarked
  • Used for login, registration, file uploads, data modification

$_GET, $_POST, $_REQUEST

PHP provides three superglobal arrays for accessing form data:

<?php
// Access GET parameters
$search = $_GET['q'] ?? '';
$category = $_GET['category'] ?? 'all';
 
// Access POST data
$username = $_POST['username'] ?? '';
$password = $_POST['password'] ?? '';
 
// $_REQUEST combines GET, POST, and COOKIE (use with caution)
$action = $_REQUEST['action'] ?? '';
?>

Form Handling

Basic form processing in a single PHP file:

Example: Complete Form Handling
php

Form Validation

Validate all input on the server side. Never rely solely on client-side validation:

<?php
$errors = [];
 
// Required fields
if (empty($_POST['username'])) {
    $errors['username'] = 'Username is required';
}
 
// Email format
if (!filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) {
    $errors['email'] = 'Invalid email address';
}
 
// String length
if (strlen($_POST['password']) < 8) {
    $errors['password'] = 'Password must be at least 8 characters';
}
 
// Numeric range
$age = (int) ($_POST['age'] ?? 0);
if ($age < 1 || $age > 150) {
    $errors['age'] = 'Please enter a valid age';
}
 
// URL validation
if (!filter_var($_POST['website'], FILTER_VALIDATE_URL)) {
    $errors['website'] = 'Invalid URL';
}
 
// Regex validation
if (!preg_match('/^[a-zA-Z0-9_]+$/', $_POST['username'])) {
    $errors['username'] = 'Username can only contain letters, numbers, and underscores';
}
?>

Form Security

Cross-Site Scripting (XSS) prevention — always escape output:

<?php
// When displaying user input in HTML
echo htmlspecialchars($userInput, ENT_QUOTES, 'UTF-8');
 
// Remove HTML tags
$clean = strip_tags($userInput, '<br><p>');  // Allow some tags
 
// Sanitize input (remove unwanted characters)
$clean = filter_var($_POST['comment'], FILTER_SANITIZE_STRING);
?>

htmlspecialchars converts:

  • &&amp;
  • <&lt;
  • >&gt;
  • "&quot;
  • '&#039; (with ENT_QUOTES)

trim, strip_tags, filter_input:

<?php
$name = trim($_POST['name']);              // Remove whitespace
$name = strip_tags($name);                 // Remove HTML tags
$email = filter_input(INPUT_POST, 'email', FILTER_SANITIZE_EMAIL);
$age = filter_input(INPUT_POST, 'age', FILTER_SANITIZE_NUMBER_INT);
?>

File Uploads

HTML form for file upload:

<form action="upload.php" method="POST" enctype="multipart/form-data">
    <input type="file" name="avatar">
    <input type="submit" value="Upload">
</form>

PHP file handling:

<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['avatar'])) {
    $file = $_FILES['avatar'];
 
    // File information
    $fileName = $file['name'];
    $fileSize = $file['size'];
    $fileTmp = $file['tmp_name'];
    $fileError = $file['error'];
    $fileType = $file['type'];
 
    // Validate
    $allowedTypes = ['image/jpeg', 'image/png', 'image/gif'];
    $maxSize = 2 * 1024 * 1024;  // 2MB
 
    if ($fileError !== UPLOAD_ERR_OK) {
        echo "Upload failed with error code: $fileError";
    } elseif (!in_array($fileType, $allowedTypes)) {
        echo "Only JPG, PNG, and GIF files are allowed";
    } elseif ($fileSize > $maxSize) {
        echo "File is too large. Maximum size is 2MB";
    } else {
        // Generate unique filename
        $extension = pathinfo($fileName, PATHINFO_EXTENSION);
        $newName = uniqid('avatar_') . '.' . $extension;
        $uploadPath = 'uploads/' . $newName;
 
        if (move_uploaded_file($fileTmp, $uploadPath)) {
            echo "File uploaded successfully: $newName";
        } else {
            echo "Failed to move uploaded file";
        }
    }
}
?>

Sticky Forms

A sticky form remembers the user's input after submission, so they don't have to retype everything if validation fails:

<input
    type="text"
    name="email"
    value="<?php echo htmlspecialchars($email ?? '', ENT_QUOTES); ?>"
>
<textarea name="message"><?php echo htmlspecialchars($message ?? '', ENT_QUOTES); ?></textarea>
 
<!-- Select/option sticky -->
<select name="country">
    <option value="US" <?= ($country ?? '') === 'US' ? 'selected' : '' ?>>United States</option>
    <option value="UK" <?= ($country ?? '') === 'UK' ? 'selected' : '' ?>>United Kingdom</option>
</select>
 
<!-- Checkbox sticky -->
<input type="checkbox" name="subscribe" value="1"
    <?= !empty($subscribe) ? 'checked' : '' ?>>
 
<!-- Radio sticky -->
<input type="radio" name="gender" value="male"
    <?= ($gender ?? '') === 'male' ? 'checked' : '' ?>>

Always validate on the server side. Client-side validation is convenient for users but can be bypassed. Server-side validation is your security boundary.

Practical Examples

Example 1: Complete Registration Form
php
Example 2: File Upload with Validation
php

Always use htmlspecialchars() when outputting form values. This prevents XSS attacks where a user might submit malicious JavaScript as their name or other field.

Exercises

Contact Form with Validation

easy

Create a contact form with fields: name, email, subject (dropdown), and message. Validate all fields. Show errors next to each field. Make the form sticky.

Expected Output:

A working contact form that validates input, shows inline errors, remembers values, and displays a success message on valid submission.

Survey Form with Multiple Question Types

medium

Create a survey form with: text inputs, radio buttons, checkboxes (multiple selections), dropdown, and a textarea. Validate that required questions are answered. Display a summary of all answers after successful submission.

Expected Output:

A dynamic survey that renders different input types, validates required fields, and shows a summary page with all answers after submission.

Profile Picture Uploader

hard

Create a profile picture upload form. Accept only JPG, PNG, and GIF files under 2MB. Validate dimensions (max 2000x2000). Generate a thumbnail version. Display the uploaded image with a preview.

Expected Output:

A form that uploads a profile picture, validates it, creates a thumbnail, and displays both the original and thumbnail

Mini Quiz

Mini Quiz

Mini Project

Mini Project: Multi-Step Registration Wizard

Build a multi-step registration form with 3 steps: Account Info (username, email, password), Personal Info (name, address, phone), and Review (summary of all data). Use POST to persist data across steps (hidden fields or session).

Requirements:

    Bonus Challenge

    Use PHP sessions instead of hidden fields to persist data across steps. Add a progress bar showing the current step.