Module 03: Headers & Metadata

Learning Objectives

Demo Files

request-inspector.php See all request metadata from $_SERVER

content-negotiation.php Return JSON or HTML based on Accept header

raw-body.php Read JSON from request body (php://input)

The $_SERVER Superglobal

PHP puts all request metadata in $_SERVER:

Key Contains
REQUEST_METHOD GET, POST, PUT, DELETE, etc.
REQUEST_URI Full request path with query string
QUERY_STRING Just the query string portion
HTTP_HOST Requested hostname
HTTP_USER_AGENT Browser identification string
HTTP_ACCEPT Content types client accepts
CONTENT_TYPE Content-Type of request body
REMOTE_ADDR Client IP address

Pattern: HTTP headers become HTTP_* in $_SERVER.

The header Accept-Language becomes $_SERVER['HTTP_ACCEPT_LANGUAGE']

Setting Response Headers

<?php
// Set content type
header('Content-Type: application/json');

// Set custom headers
header('X-Custom-Header: my-value');

// Set status code
http_response_code(404);

// Redirect (always exit after!)
header('Location: /other-page.php');
exit;
?>

Headers Must Come First!

header() must be called before any output.

Even a single space or newline before <?php will cause an error.

// WRONG - whitespace before PHP tag
 <?php
header('Content-Type: application/json'); // ERROR!

// WRONG - echo before header
<?php
echo "Hello";
header('Location: /'); // ERROR!

// RIGHT - header first
<?php
header('Content-Type: application/json');
echo json_encode($data);

Reading Raw Request Body

For JSON APIs, form data isn't in $_POST. Read it directly:

<?php
// Read raw request body
$rawBody = file_get_contents('php://input');

// Parse as JSON
$data = json_decode($rawBody, true);

if ($data === null && json_last_error() !== JSON_ERROR_NONE) {
    http_response_code(400);
    echo json_encode(['error' => 'Invalid JSON']);
    exit;
}

// Now $data is a PHP array
echo "Received: " . $data['name'];
?>

Testing with curl

# GET request
curl http://localhost:8000/content-negotiation.php

# Request JSON
curl -H "Accept: application/json" http://localhost:8000/content-negotiation.php

# POST JSON data
curl -X POST \
     -H "Content-Type: application/json" \
     -d '{"name":"Alice","email":"alice@example.com"}' \
     http://localhost:8000/raw-body.php

← Previous: Form Handling | Tutorial Home | Next: Sessions →