Course outline

PHP / Basic: values and request foundations / Lesson 5

HTTP input, forms, and validation boundaries

Interpret request data without assuming superglobals are trusted records. Separate method checks, input shape, domain validation, and error feedback using synthetic submissions.

About 4 min readContent reviewed
On this page

Lesson goals

  • Distinguish transport shape from domain values.
  • Validate scalar input without loose false checks.
  • Design safe rejection and correction behavior.

A request is external evidence, not a trusted object

A server adapter reads a request method, path, headers, cookies, and body according to its execution interface. PHP populates superglobals for supported input formats, but values still originate outside the trust boundary. Form controls commonly produce strings and can produce arrays through naming conventions; JSON bodies follow a different decoding path. Do not assume $_POST represents every possible request body or that a hidden input is authoritative. Convert the external representation into a small validated record before calling domain functions, keeping the raw source available only as needed for safe correction or diagnosis.

Validate syntax and range explicitly

The quantity rule here accepts a string that the integer validator recognizes within one through twenty. The parser rejects arrays before filtering and returns null for invalid input, preserving a distinct domain result. filter_var returns false on validation failure for this filter, so strict comparison matters when zero is a valid value in another contract. Do not silently trim or normalize identifiers if the product requires exact bytes. Numeric parsing policies, leading zeros, signs, and localization should be agreed and tested rather than inferred from a function name. A cast alone is not a substitute.

php Scalar shape before integer validation
<?php
declare(strict_types=1);
function quantity(mixed $raw): ?int {
    if (!is_string($raw)) { return null; }
    $value = filter_var($raw, FILTER_VALIDATE_INT, ["options" => ["min_range" => 1, "max_range" => 20]]);
    return $value === false ? null : $value;
}
echo quantity("3"), PHP_EOL;
echo quantity("3x") === null ? "invalid
" : "valid
";
echo quantity(["3"]) === null ? "invalid shape
" : "valid
";
Expected output
3
invalid
invalid shape

The parser rejects both malformed text and an array without treating either as a plausible quantity.

Method and validation decisions precede effects

Choose allowed methods and content types before creating a reservation. A page read should not create an enrollment merely because a query parameter asks it to. A state-changing form needs server-side permission checks and a CSRF strategy appropriate to its session design, not just client JavaScript validation. Return a defined rejection for wrong shape or invalid values and preserve legitimate entered fields for correction. The local decision model below produces status-like outcomes without opening a server or changing state; real HTTP emission is a separate adapter responsibility. Keep that evidence distinction visible.

php A pure request-decision model
<?php
declare(strict_types=1);
function decide(string $method, array $input): array {
    if ($method !== "POST") { return ["status" => 405]; }
    if (!isset($input["name"]) || !is_string($input["name"]) || trim($input["name"]) === "") {
        return ["status" => 422, "error" => "name required"];
    }
    return ["status" => 200, "name" => trim($input["name"])];
}
echo json_encode(decide("GET", []), JSON_THROW_ON_ERROR), PHP_EOL;
echo json_encode(decide("POST", ["name" => "  Ada  "]), JSON_THROW_ON_ERROR), PHP_EOL;
Expected output
{"status":405}
{"status":200,"name":"Ada"}

These integers model outcomes, not emitted HTTP responses. No enrollment or session is created.

Validation should enable correction

Associate each error with its field and explain the expected format in safe text. Preserve valid inputs unless retaining them would expose sensitive data, and escape them when rendering the correction form. Validation messages must not contain raw SQL, file paths, or session identifiers. Distinguish missing input, invalid type, invalid format, and rejected domain state when those distinctions help the user or caller. Do not let an unrelated invalid field prevent every test from reaching the quantity rule. Test focused failures with otherwise valid data so each rejection demonstrates the intended validator.

Bound input size and uploaded-file behavior

A valid field value can still arrive inside an oversized request or an unexpected multipart shape. Request limits, upload error codes, file size, media inspection, and storage naming are separate concerns from text validation. Never trust a client filename as a destination path or execute uploaded content. Keep a bounded server-side policy and store outside executable paths where appropriate. This course’s examples use no uploaded files or real requests; use an isolated fixture when studying those APIs. Record limitations so a passing scalar parser is not reported as complete form or upload security.

Common errors and fixes

A form field arrives as an array unexpectedly

Why it happens
The caller assumes every external value is a scalar string.
How to fix it
Validate shape before string or numeric operations.
Prevent it next time
Include array-shaped input in boundary tests.

A GET request changes enrollment state

Why it happens
Read navigation and write effects are mixed.
How to fix it
Define allowed methods and guard state-changing handlers.
Prevent it next time
Review method, permission, and CSRF checks together.

Rejected input loses every valid field

Why it happens
Error handling ignores the correction task.
How to fix it
Preserve safe valid data and attach clear field errors.
Prevent it next time
Test correction and successful resubmission as one flow.

Check your understanding

1. A zero count is permitted and filter_var returns zero. Should if (!$value) reject it?

Show worked solution

No. Compare $value === false for this validation filter, then apply the allowed range separately. A truthiness check would conflate a valid zero with failure. Test zero, malformed text, and missing input as different cases rather than using one generic invalid test.

2. A hidden price field says 1 cent. What should the server trust?

Show worked solution

Use the validated course identifier to obtain the authoritative server-side price and permission context. The hidden field can be presentation data or a consistency hint, but is editable client input. Reject inconsistent or unauthorized actions before writing a reservation or payment effect.

Key takeaways

  • Validate external shape before converting values.
  • Method, permission, CSRF, and correction are separate parts of a form contract.

Official references