Handling HTTP requests

PHP · Essentials · 14 min

This is what PHP does on every request, and understanding it makes frameworks far less magical.

When a web server runs your script, PHP fills superglobals with the request data:

  • $_GET: query-string parameters (?page=2).
  • $_POST: form fields from a application/x-www-form-urlencoded or multipart/form-data POST.
  • $_SERVER: request metadata such as REQUEST_METHOD, REQUEST_URI and HTTP_* headers.
  • $_COOKIE, $_FILES, and $_SESSION (after session_start()).

For JSON request bodies read the raw input: json_decode(file_get_contents('php://input'), true).

Everything in these arrays is a string (or array) controlled by the client, so validate it. filter_input(INPUT_GET, 'page', FILTER_VALIDATE_INT) returns an int, false on bad input, or null when the parameter is missing.

To respond, echo the body, set the status with http_response_code(404) and headers with header('Content-Type: application/json'). Headers must be sent before any output.

Escape every value you put into HTML with htmlspecialchars($value). It converts <, >, & and quotes so user input can't inject scripts (XSS). PHP 8.1 made ENT_QUOTES the default, so single quotes are escaped too.

For local development, PHP has a built-in server: php -S localhost:8000 serves the current directory. It is single-threaded and not for production.

Example

<?php
// index.php: run `php -S localhost:8000` and open
// http://localhost:8000/?name=<b>Ann</b>&page=2
$name = $_GET['name'] ?? 'world';
$page = filter_input(INPUT_GET, 'page', FILTER_VALIDATE_INT) ?: 1;

if (($_SERVER['REQUEST_METHOD'] ?? 'GET') === 'POST') {
    $data = json_decode(file_get_contents('php://input'), true);
    header('Content-Type: application/json');
    http_response_code(201);
    echo json_encode(['received' => $data]);
    exit;
}

$safe = htmlspecialchars($name);
echo "<h1>Hello, $safe</h1><p>Page $page</p>";
// The <b> tags arrive escaped, so the browser shows them as text

Remember

  • Request data arrives in $_GET, $_POST, $_SERVER and friends, always as untrusted strings
  • Send headers and status codes before any output
  • Escape output with htmlspecialchars to prevent XSS

Watch out for

  • Echoing $_GET values into HTML without htmlspecialchars, creating an XSS hole.
  • Printing something before calling header(), which triggers 'headers already sent'.

Check yourself

  1. Why must header() calls come before any echo?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: www.php.net/manual/en/language.variables.superglobals.php

Handling HTTP requests · PHP · Topolearn