Skip to content
PHP Forms — Handling, Validation & Security Complete Guide

PHP Forms — Handling, Validation & Security Complete Guide

DodaTech Updated Jun 6, 2026 6 min read

PHP forms are how users send data to your web server — collecting, validating, and processing input safely is the most common task in web development and the most common source of security vulnerabilities.

What You’ll Learn

By the end of this tutorial, you’ll build secure forms with proper validation, error handling, file uploads, CSRF protection, and sticky form persistence.

Why Form Handling Matters

Forms are the gateway between users and your application. Durga Antivirus Pro uses forms for license activation, threat report submissions, and scan configuration. Doda Browser uses forms for login, sync settings, and bookmark import. DodaZIP uses forms for file upload and extraction options. Every interaction starts with a form — if it’s insecure, your entire application is at risk.

Forms Learning Path

    flowchart LR
  A[Functions] --> B[Arrays]
  B --> C[Forms]
  C --> D[Advanced OOP]
  D --> E[Frameworks]
  C --> F{You Are Here}
  style F fill:#f90,color:#fff
  
Prerequisites: PHP basics through arrays. Understanding HTML forms is essential. Knowledge of HTTP methods (GET/POST) helps.

How Form Data Flows (The “Why” First)

Think of a form like a paper application form. The user fills it out (browser), puts it in an envelope (HTTP request), and mails it to you (server). You open the envelope, read the answers ($_GET or $_POST), and decide what to do.

    flowchart LR
  A[User fills form] --> B[Browser submits]
  B --> C{Method?}
  C -->|GET| D[URL parameters]
  C -->|POST| E[Request body]
  D --> F[$_GET]
  E --> F
  F --> G{Validate}
  G -->|Valid| H[Process data]
  G -->|Invalid| I[Show errors]
  I --> A
  

GET vs POST — Which to Use?

FeatureGETPOST
Data locationURL query stringRequest body
Visible in URLYesNo
BookmarkableYesNo
Size limit~2000 charsLarge (file uploads)
SecurityLowBetter
Use caseSearches, filtersLogins, orders, uploads

Rule of thumb: Use GET for reading data (search pages, filters). Use POST for writing data (signups, orders, file uploads).

Basic Form with Validation

<?php
$name = $email = "";
$nameErr = $emailErr = "";

if ($_SERVER["REQUEST_METHOD"] === "POST") {
    $name = trim($_POST["name"] ?? "");
    $email = trim($_POST["email"] ?? "");

    if (empty($name)) {
        $nameErr = "Name is required";
    } elseif (!preg_match("/^[a-zA-Z\s]+$/", $name)) {
        $nameErr = "Only letters and spaces allowed";
    }

    if (empty($email)) {
        $emailErr = "Email is required";
    } elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        $emailErr = "Invalid email format";
    }
}
?>
<form method="post">
    Name: <input type="text" name="name" value="<?= htmlspecialchars($name) ?>">
    <span style="color:red;"><?= $nameErr ?></span><br>
    Email: <input type="text" name="email" value="<?= htmlspecialchars($email) ?>">
    <span style="color:red;"><?= $emailErr ?></span><br>
    <input type="submit" value="Submit">
</form>

Line by line:

  1. $_SERVER["REQUEST_METHOD"] === "POST" — check if the form was submitted
  2. trim() — remove whitespace from both ends
  3. preg_match() — validate format using regex pattern
  4. filter_var(... FILTER_VALIDATE_EMAIL) — PHP’s built-in email validator
  5. htmlspecialchars()critical: prevents XSS by escaping HTML characters

File Uploads

<form method="post" enctype="multipart/form-data">
    <input type="file" name="document">
    <input type="submit" value="Upload">
</form>

<?php
if ($_SERVER["REQUEST_METHOD"] === "POST" && isset($_FILES["document"])) {
    $file = $_FILES["document"];
    $allowedTypes = ["application/pdf", "image/jpeg", "image/png"];
    $maxSize = 5 * 1024 * 1024;  // 5MB

    if ($file["error"] !== UPLOAD_ERR_OK) {
        echo "Upload failed";
    } elseif (!in_array($file["type"], $allowedTypes)) {
        echo "File type not allowed";
    } elseif ($file["size"] > $maxSize) {
        echo "File too large";
    } else {
        $ext = pathinfo($file["name"], PATHINFO_EXTENSION);
        $dest = "uploads/" . uniqid() . "." . $ext;
        move_uploaded_file($file["tmp_name"], $dest);
        echo "Uploaded successfully";
    }
}
?>

Critical: Always validate MIME type, not just file extension. A file named virus.php.jpg might be executed as PHP.

CSRF Protection — The Hidden Token

Cross-Site Request Forgery (CSRF) tricks authenticated users into submitting unwanted actions. The fix is a unique token in each form:

<?php session_start();
if (empty($_SESSION["csrf_token"])) {
    $_SESSION["csrf_token"] = bin2hex(random_bytes(32));
} ?>
<form method="post">
    <input type="hidden" name="csrf_token" value="<?= $_SESSION["csrf_token"] ?>">
    <button type="submit">Update Email</button>
</form>
<?php
if ($_SERVER["REQUEST_METHOD"] === "POST") {
    if (!hash_equals($_SESSION["csrf_token"], $_POST["csrf_token"] ?? "")) {
        die("CSRF validation failed");
    }
    // Process form...
}
?>

Common Mistakes

1. No Server-Side Validation

JavaScript validation is for UX only. Malicious users can bypass client-side checks or send raw POST requests. Always validate on the server.

2. Directly Echoing Raw Input (XSS)

// DANGEROUS
echo "Hello, " . $_GET["name"];

// SAFE
echo "Hello, " . htmlspecialchars($_GET["name"], ENT_QUOTES, "UTF-8");

3. Trusting File Extensions

Check the MIME type with finfo_file(), not just the extension. Attackers can rename shell.php to shell.pdf.

4. Forgetting enctype=“multipart/form-data”

File uploads won’t work without this attribute on the <form> tag.

5. Not Regenerating CSRF Tokens

Using the same token for the entire session weakens security. Regenerate after successful submission.

Practice Questions

1. What’s the difference between $_GET, $_POST, and $_REQUEST?

$_GET has URL query parameters. $_POST has request body data. $_REQUEST combines both plus cookies. Use $_GET and $_POST explicitly.

2. Why is htmlspecialchars() necessary when outputting form values?

It prevents XSS (Cross-Site Scripting). If a user submits <script>alert('xss')</script>, without escaping, the script runs in your page.

3. How do you validate an email address in PHP?

filter_var($email, FILTER_VALIDATE_EMAIL) — returns the email if valid, false otherwise.

4. What must you add to a form for file uploads?

enctype="multipart/form-data" on the <form> tag.

5. Challenge: Build a registration form that validates username (3-20 chars, alphanumeric), email, password (min 8 chars), and password confirmation match.

<?php
$errors = [];
if ($_SERVER["REQUEST_METHOD"] === "POST") {
    $username = trim($_POST["username"] ?? "");
    $email = trim($_POST["email"] ?? "");
    $password = $_POST["password"] ?? "";
    $confirm = $_POST["confirm"] ?? "";

    if (!preg_match("/^[a-zA-Z0-9_]{3,20}$/", $username))
        $errors[] = "Invalid username";
    if (!filter_var($email, FILTER_VALIDATE_EMAIL))
        $errors[] = "Invalid email";
    if (strlen($password) < 8)
        $errors[] = "Password too short";
    if ($password !== $confirm)
        $errors[] = "Passwords don't match";

    if (empty($errors)) echo "Registration successful!";
}
?>

FAQ

How do I prevent XSS in forms?
Always use htmlspecialchars() when outputting user data in HTML. Never echo raw input. Use ENT_QUOTES for both single and double quotes.
Why is my file upload failing?
Check: enctype="multipart/form-data" on form, upload_max_filesize in php.ini, directory write permissions, and $_FILES["file"]["error"] for error codes.
What is CSRF and how do I prevent it?
CSRF tricks authenticated users into unintended actions. Prevent with unique per-form tokens stored in session and validated on submission.
How do I make sticky forms?
Keep the user’s input after validation errors by setting value="<?= htmlspecialchars($input) ?>" on form fields.

Try It Yourself

Create a secure registration form combining validation, CSRF protection, and sticky fields. Run with php -S localhost:8000 and test submitting invalid and valid data.

What’s Next

LessonDescription
https://tutorials.dodatech.com/backend/php/php-advanced/Sessions, OOP, PDO database
https://tutorials.dodatech.com/backend/php/php-reference/PHP functions cheatsheet
https://tutorials.dodatech.com/backend/nodejs/nodejs-basics/Server-side JavaScript
SQL InjectionPreventing SQL injection
LaravelForm handling in Laravel

What’s Next

Congratulations on completing this Php Forms tutorial! Here’s where to go from here:

  • Practice daily — Consistency is more important than long study sessions
  • Build a project — Apply what you learned by building something real
  • Explore related topics — Check out other tutorials in the same category
  • Join the community — Discuss with other learners and share your progress

Remember: every expert was once a beginner. Keep coding!

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro