Web Development /PHP Programming / Lesson
Web Development

Working with Forms

Learn how PHP processes HTML form submissions, accesses submitted values, validates and sanitizes user input, handles different form controls, preserves submitted values, displays errors, and builds secure server-side form workflows.

🎯

Learning Objectives

["Explain how HTML forms send data from a browser to a PHP application.","Create HTML forms that submit data using GET and POST methods.","Understand the relationship between form field names and PHP superglobal arrays.","Access submitted form values using $_POST and $_GET.","Detect whether a form has been submitted before processing its data.","Validate required fields and common input types on the server.","Understand the difference between validation and sanitization.","Safely escape submitted values when displaying them in HTML.","Handle checkboxes, radio buttons, select fields, text areas, and multiple-value fields.","Build a practical secure PHP form workflow with validation, error handling, and clear user feedback."]

📖

Lesson Content

Introduction to PHP Forms

Forms are one of the main ways users interact with web applications. A form allows a visitor to enter information and send it to a server for processing.

Examples include:

  • Registration forms
  • Login forms
  • Contact forms
  • Search forms
  • Student enrollment forms
  • Application forms
  • Feedback forms
  • Payment information forms

HTML is responsible for presenting the form in the browser, while PHP can process the submitted information on the server.

1. Basic HTML Form

A simple form can contain input fields and a submit button.

<form method="post" action="process.php">
    <label for="name">Name:</label>
    <input type="text" id="name" name="name">

    <button type="submit">Submit</button>
</form>

The method determines how the browser sends the information, while the action specifies the URL that should process the submission.

2. The name Attribute

The name attribute is important because PHP uses it to identify submitted form values.

<input
    type="text"
    name="student_name"
>

If the user enters Daniel, a POST request can contain a value associated with the key student_name.

3. Processing POST Data

When a form uses the POST method, PHP makes the submitted values available through the $_POST superglobal array.

<?php

$name = $_POST['student_name'] ?? '';

echo $name;

?>

The null coalescing operator prevents an undefined-key warning when the field is not present.

4. Detecting Form Submission

Before processing form data, it is useful to check whether the expected request method was used.

<?php

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    echo "The form was submitted.";
}

?>

This prevents processing logic from running during a normal page request.

5. GET Forms

A form can also use the GET method.

<form method="get" action="search.php">
    <label for="keyword">Search:</label>
    <input type="search" id="keyword" name="keyword">

    <button type="submit">Search</button>
</form>

GET values are available through $_GET.

<?php

$keyword = $_GET['keyword'] ?? '';

echo $keyword;

?>

GET is commonly used for searches, filters, and other requests where the submitted information can safely appear in the URL.

6. POST Versus GET

GET and POST have different purposes.

GETPOST
Data is commonly included in the URL.Data is sent in the request body.
Useful for searches and filters.Commonly used for creating or changing data.
Values may be bookmarked or shared as part of the URL.Submitted values are not normally shown in the URL.
Should not be used for sensitive information.Still requires HTTPS and proper server-side security.

Using POST does not by itself make sensitive information secure. HTTPS, proper validation, authorization, and other security controls are still required.

7. Reading Text Input

<form method="post">
    <label for="name">Full Name:</label>
    <input type="text" id="name" name="name">

    <button type="submit">Submit</button>
</form>

PHP can retrieve the value using:

<?php

$name = $_POST['name'] ?? '';

?>

8. Required Fields

HTML can provide client-side assistance using the required attribute.

<input
    type="text"
    name="name"
    required
>

However, browser validation should not be considered sufficient security. Server-side PHP validation is still required because clients can send requests without using the normal browser interface.

9. Server-side Validation

Validation checks whether submitted information meets the rules required by the application.

<?php

$name = trim($_POST['name'] ?? '');

$errors = [];

if ($name === '') {
    $errors[] = 'Name is required.';
}

if (empty($errors)) {
    echo "Form is valid.";
}

?>

10. Validation Versus Sanitization

Validation asks whether data is acceptable. Sanitization attempts to clean or transform data for a particular purpose.

For example, if an application requires an integer, validation should confirm that the submitted value is an acceptable integer.

<?php

$age = filter_input(
    INPUT_POST,
    'age',
    FILTER_VALIDATE_INT
);

if ($age === false || $age === null) {
    echo "Please provide a valid age.";
}

?>

Sanitization should not be used as a substitute for validation.

11. Trimming Input

The trim() function removes whitespace from the beginning and end of a string.

<?php

$name = trim($_POST['name'] ?? '');

?>

This is useful for fields such as names, usernames, and text values where accidental surrounding spaces are not meaningful.

12. Validating Email Addresses

PHP provides a filter for validating email addresses.

<?php

$email = filter_input(
    INPUT_POST,
    'email',
    FILTER_VALIDATE_EMAIL
);

if ($email === false || $email === null) {
    echo "Please enter a valid email address.";
}

?>

13. Validating Integers

<?php

$age = filter_input(
    INPUT_POST,
    'age',
    FILTER_VALIDATE_INT
);

if ($age === false || $age === null) {
    echo "Age must be a valid integer.";
}

?>

14. Validating Numeric Ranges

Validation can also enforce a specific range.

<?php

$age = filter_input(
    INPUT_POST,
    'age',
    FILTER_VALIDATE_INT
);

if (
    $age === false ||
    $age === null ||
    $age < 13 ||
    $age > 100
) {
    echo "Please enter an age between 13 and 100.";
}

?>

15. Validating Select Fields

A select field may contain a limited set of acceptable values.

<select name="course">
    <option value="">Select a course</option>
    <option value="web-development">Web Development</option>
    <option value="data-analysis">Data Analysis</option>
    <option value="cyber-security">Cyber Security</option>
</select>

Server-side validation should verify that the submitted value belongs to the allowed set.

<?php

$allowedCourses = [
    'web-development',
    'data-analysis',
    'cyber-security'
];

$course = $_POST['course'] ?? '';

if (!in_array($course, $allowedCourses, true)) {
    echo "Please select a valid course.";
}

?>

16. Radio Buttons

Radio buttons allow a user to select one option from a group.

<label>
    <input type="radio" name="mode" value="online">
    Online
</label>

<label>
    <input type="radio" name="mode" value="physical">
    Physical
</label>

PHP can retrieve the selected value using the common field name.

<?php

$mode = $_POST['mode'] ?? '';

?>

17. Checkboxes

A single checkbox can submit a value when it is checked.

<label>
    <input
        type="checkbox"
        name="terms"
        value="accepted"
    >
    I accept the terms.
</label>

PHP can check the submitted value.

<?php

$termsAccepted = isset($_POST['terms']);

if (!$termsAccepted) {
    echo "You must accept the terms.";
}

?>

18. Multiple Checkboxes

Multiple checkboxes can use array notation in their names.

<label>
    <input
        type="checkbox"
        name="skills[]"
        value="html"
    >
    HTML
</label>

<label>
    <input
        type="checkbox"
        name="skills[]"
        value="css"
    >
    CSS
</label>

<label>
    <input
        type="checkbox"
        name="skills[]"
        value="php"
    >
    PHP
</label>

PHP can receive the selected values as an array.

<?php

$skills = $_POST['skills'] ?? [];

if (!is_array($skills)) {
    $skills = [];
}

foreach ($skills as $skill) {
    echo $skill . "<br>";
}

?>

19. Textareas

A textarea is useful for longer text.

<textarea
    name="message"
    rows="5"
    cols="40"
></textarea>

PHP can retrieve the submitted message.

<?php

$message = trim($_POST['message'] ?? '');

?>

20. File Inputs

File uploads use an input with type="file".

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

    <button type="submit">
        Upload
    </button>
</form>

Uploaded files are represented through the $_FILES superglobal.

<?php

if (isset($_FILES['document'])) {
    $file = $_FILES['document'];

    echo $file['name'];
}

?>

File uploads require additional security controls such as file type validation, size limits, safe storage locations, generated filenames, and appropriate access controls. Never trust the original filename or MIME type supplied by the client.

21. Escaping Output

Data submitted by users should not be inserted into HTML without appropriate output escaping.

<?php

$name = $_POST['name'] ?? '';

echo htmlspecialchars(
    $name,
    ENT_QUOTES,
    'UTF-8'
);

?>

htmlspecialchars() helps prevent submitted text from being interpreted as HTML when displayed in an HTML context.

22. Why Validation Alone Is Not Enough

Suppose a form asks for a student\’s name. Validation can confirm that a name is present, but the application still needs to consider how that value is used.

Different contexts require different security techniques:

  • HTML output requires appropriate HTML escaping.
  • SQL queries should use prepared statements.
  • URLs require appropriate URL handling.
  • Shell commands should generally avoid incorporating untrusted input.
  • File operations require strict validation and safe paths.

23. Preserving Submitted Values

When a form contains errors, it is often helpful to preserve the user’s valid input.

<?php

$name = $_POST['name'] ?? '';

?>

<input
    type="text"
    name="name"
    value="<?php echo htmlspecialchars(
        $name,
        ENT_QUOTES,
        'UTF-8'
    ); ?>"
>

Output escaping is important because the value originated from the user.

24. Displaying Validation Errors

<?php

$errors = [];

$name = trim($_POST['name'] ?? '');
$email = trim($_POST['email'] ?? '');

if ($name === '') {
    $errors[] = 'Name is required.';
}

if (
    filter_var($email, FILTER_VALIDATE_EMAIL) === false
) {
    $errors[] = 'A valid email address is required.';
}

if (!empty($errors)) {
    foreach ($errors as $error) {
        echo '<p>';
        echo htmlspecialchars(
            $error,
            ENT_QUOTES,
            'UTF-8'
        );
        echo '</p>';
    }
}

?>

25. A Complete Basic Form

<?php

$errors = [];
$name = '';
$email = '';

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

    if ($name === '') {
        $errors[] = 'Name is required.';
    }

    if (
        filter_var($email, FILTER_VALIDATE_EMAIL) === false
    ) {
        $errors[] = 'A valid email address is required.';
    }

    if (empty($errors)) {
        echo "Registration is valid.";
    }
}

?>

<form method="post">

    <label for="name">Name</label>
    <input
        type="text"
        id="name"
        name="name"
        value="<?php echo htmlspecialchars(
            $name,
            ENT_QUOTES,
            'UTF-8'
        ); ?>"
    >

    <label for="email">Email</label>
    <input
        type="email"
        id="email"
        name="email"
        value="<?php echo htmlspecialchars(
            $email,
            ENT_QUOTES,
            'UTF-8'
        ); ?>"
    >

    <button type="submit">
        Register
    </button>

</form>

26. Form Processing Flow

A typical PHP form workflow can be organized into the following steps:

  1. Display the form.
  2. Wait for a submission.
  3. Check the HTTP request method.
  4. Read submitted values.
  5. Normalize appropriate input such as trimming whitespace.
  6. Validate the submitted data.
  7. Perform authorization and security checks when required.
  8. Process valid data.
  9. Store or send the data when appropriate.
  10. Display a clear success or error response.

27. Server-side Validation Example

<?php

$errors = [];

$name = trim($_POST['name'] ?? '');
$course = $_POST['course'] ?? '';
$email = trim($_POST['email'] ?? '');

$allowedCourses = [
    'web-development',
    'data-analysis',
    'cyber-security'
];

if ($name === '') {
    $errors['name'] = 'Name is required.';
}

if (
    filter_var($email, FILTER_VALIDATE_EMAIL) === false
) {
    $errors['email'] = 'Enter a valid email address.';
}

if (!in_array($course, $allowedCourses, true)) {
    $errors['course'] = 'Select a valid course.';
}

if (empty($errors)) {
    echo "Form submitted successfully.";
}

?>

28. Organizing Form Data

Instead of working with many separate variables, related form values can be organized into an array.

<?php

$formData = [
    'name' => trim($_POST['name'] ?? ''),
    'email' => trim($_POST['email'] ?? ''),
    'course' => $_POST['course'] ?? ''
];

print_r($formData);

?>

This can make larger form-processing routines easier to organize.

29. Avoid Trusting Client-side Input

HTML attributes such as required, maxlength, min, and pattern are useful for user experience, but they do not replace server-side validation.

A malicious or modified request can bypass browser restrictions. PHP must therefore validate important rules on the server.

30. Cross-Site Request Forgery Protection

Forms that perform sensitive actions should include protection against Cross-Site Request Forgery, commonly known as CSRF.

In WordPress, nonces are commonly used for this purpose.

<?php

wp_nonce_field(
    'dwallnet_student_registration',
    'dwallnet_registration_nonce'
);

?>

The server should verify the nonce before performing the protected action.

<?php

if (
    !isset($_POST['dwallnet_registration_nonce']) ||
    !wp_verify_nonce(
        sanitize_text_field(
            wp_unslash(
                $_POST['dwallnet_registration_nonce']
            )
        ),
        'dwallnet_student_registration'
    )
) {
    wp_die('Security verification failed.');
}

?>

WordPress forms should follow the platform’s current nonce and capability-checking practices.

31. Form Processing and Database Storage

After validation, an application may store submitted information in a database.

Database operations should use prepared statements rather than concatenating untrusted input into SQL queries.

<?php

$name = trim($_POST['name'] ?? '');

$wpdb->insert(
    $table_name,
    [
        'name' => $name
    ],
    [
        '%s'
    ]
);

?>

When using WordPress, the $wpdb API provides methods such as insert(), update(), and prepare() for database operations.

32. Form Validation with Functions

Form validation logic can be moved into functions so that it can be reused.

<?php

function validateEmail(string $email): bool {
    return filter_var(
        $email,
        FILTER_VALIDATE_EMAIL
    ) !== false;
}

function validateRequired(string $value): bool {
    return trim($value) !== '';
}

$email = trim($_POST['email'] ?? '');

if (!validateEmail($email)) {
    echo "Invalid email.";
}

?>

33. Form Security Checklist

  • Use HTTPS for applications handling sensitive information.
  • Validate submitted values on the server.
  • Use appropriate output escaping.
  • Use prepared database queries.
  • Protect state-changing forms against CSRF.
  • Check user permissions before performing protected actions.
  • Do not trust client-side validation alone.
  • Restrict file uploads carefully.
  • Do not expose sensitive information in error messages.
  • Use appropriate authentication and authorization controls.

34. Practical Student Registration Form

<?php

$errors = [];
$success = '';

$name = '';
$email = '';
$course = '';

$allowedCourses = [
    'web-development',
    'data-analysis',
    'cyber-security'
];

if ($_SERVER['REQUEST_METHOD'] === 'POST') {

    $name = trim($_POST['name'] ?? '');
    $email = trim($_POST['email'] ?? '');
    $course = $_POST['course'] ?? '';

    if ($name === '') {
        $errors['name'] = 'Please enter your name.';
    }

    if (
        filter_var($email, FILTER_VALIDATE_EMAIL) === false
    ) {
        $errors['email'] = 'Please enter a valid email.';
    }

    if (!in_array($course, $allowedCourses, true)) {
        $errors['course'] = 'Please select a valid course.';
    }

    if (empty($errors)) {
        $success = 'Registration submitted successfully.';
    }
}

?>

<form method="post">

    <label for="name">Full Name</label>
    <input
        type="text"
        id="name"
        name="name"
        value="<?php echo htmlspecialchars(
            $name,
            ENT_QUOTES,
            'UTF-8'
        ); ?>"
    >

    <label for="email">Email</label>
    <input
        type="email"
        id="email"
        name="email"
        value="<?php echo htmlspecialchars(
            $email,
            ENT_QUOTES,
            'UTF-8'
        ); ?>"
    >

    <label for="course">Course</label>

    <select id="course" name="course">
        <option value="">Select a course</option>

        <option value="web-development">
            Web Development
        </option>

        <option value="data-analysis">
            Data Analysis
        </option>

        <option value="cyber-security">
            Cyber Security
        </option>
    </select>

    <button type="submit">
        Register
    </button>

</form>

35. Common Form Mistakes

  • Processing input without checking whether the form was submitted.
  • Assuming every expected field exists.
  • Trusting browser-side validation as the only validation layer.
  • Displaying user input directly in HTML.
  • Building SQL queries by concatenating submitted values.
  • Failing to protect sensitive state-changing forms against CSRF.
  • Accepting arbitrary values when only a known set is valid.
  • Ignoring errors during validation.
  • Accepting uploaded files without strict validation.

36. Best Practices for PHP Forms

  • Give every important input a meaningful name.
  • Use the appropriate HTTP method for the operation.
  • Validate data on the server.
  • Normalize data where appropriate before validation.
  • Escape output according to its context.
  • Use prepared database queries.
  • Use CSRF protection for state-changing requests.
  • Check authorization before protected operations.
  • Give users clear validation messages.
  • Preserve valid submitted values when redisplaying a form.
  • Keep validation and processing logic organized into reusable functions.

Lesson Summary

PHP forms provide a bridge between browser interfaces and server-side application logic. HTML collects information while PHP receives, validates, processes, and potentially stores that information.

The most important concepts in this lesson are form methods, $_GET, $_POST, validation, sanitization, output escaping, checkboxes, radio buttons, select fields, textareas, file uploads, CSRF protection, and secure database processing.

A professional PHP form should never assume that information supplied by a browser is trustworthy. The server must validate important rules and apply appropriate security controls before using submitted data.

💻

Code Example

<?php

$errors = [];

$name = trim($_POST['name'] ?? '');
$email = trim($_POST['email'] ?? '');
$course = $_POST['course'] ?? '';

$allowedCourses = [
    'web-development',
    'data-analysis',
    'cyber-security',
];

if ($_SERVER['REQUEST_METHOD'] === 'POST') {

    if ($name === '') {
        $errors['name'] = 'Name is required.';
    }

    if (
        filter_var($email, FILTER_VALIDATE_EMAIL) === false
    ) {
        $errors['email'] = 'A valid email address is required.';
    }

    if (!in_array($course, $allowedCourses, true)) {
        $errors['course'] = 'Please select a valid course.';
    }

    if (empty($errors)) {
        echo 'Registration submitted successfully.';
    }
}
?>

<form method="post">

    <label for="name">Full Name</label>

    <input
        type="text"
        id="name"
        name="name"
        value="<?php echo htmlspecialchars(
            $name,
            ENT_QUOTES,
            'UTF-8'
        ); ?>"
    >

    <?php if (isset($errors['name'])) : ?>
        <p>
            <?php
            echo htmlspecialchars(
                $errors['name'],
                ENT_QUOTES,
                'UTF-8'
            );
            ?>
        </p>
    <?php endif; ?>

    <label for="email">Email</label>

    <input
        type="email"
        id="email"
        name="email"
        value="<?php echo htmlspecialchars(
            $email,
            ENT_QUOTES,
            'UTF-8'
        ); ?>"
    >

    <?php if (isset($errors['email'])) : ?>
        <p>
            <?php
            echo htmlspecialchars(
                $errors['email'],
                ENT_QUOTES,
                'UTF-8'
            );
            ?>
        </p>
    <?php endif; ?>

    <label for="course">Course</label>

    <select id="course" name="course">
        <option value="">Select a course</option>

        <option
            value="web-development"
            <?php selected($course, 'web-development'); ?>
        >
            Web Development
        </option>

        <option
            value="data-analysis"
            <?php selected($course, 'data-analysis'); ?>
        >
            Data Analysis
        </option>

        <option
            value="cyber-security"
            <?php selected($course, 'cyber-security'); ?>
        >
            Cyber Security
        </option>
    </select>

    <?php if (isset($errors['course'])) : ?>
        <p>
            <?php
            echo htmlspecialchars(
                $errors['course'],
                ENT_QUOTES,
                'UTF-8'
            );
            ?>
        </p>
    <?php endif; ?>

    <button type="submit">
        Register
    </button>

</form>
⭐

Key Takeaways

["HTML forms collect information while PHP processes submitted data on the server.","The name attribute identifies form values when they are submitted.","POST data is available through $_POST and GET data through $_GET.","Always check the request method before processing a form.","Client-side validation improves user experience but does not replace server-side validation.","Validation determines whether submitted data meets application requirements.","Sanitization and validation serve different purposes and should not be treated as interchangeable.","User-controlled values should be escaped appropriately before being displayed in HTML.","Prepared database queries should be used when storing or retrieving data based on user input.","State-changing forms should include CSRF protection and appropriate authorization checks.","File uploads require strict validation, safe storage, size restrictions, and careful access control.","Clear validation errors and preserved form values improve the usability of PHP forms."]

Enjoying this lesson?

Sign in to your Dwallnet Academy student account to track your learning progress and mark lessons as complete.

Sign In to Track Progress