Controlling HTTP responses with PHP's header functions
The $_SERVER Superglobal
PHP puts all request metadata into the $_SERVER superglobal array. This includes the HTTP method, URL path, query string, and all request headers:
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
Setting Response Headers
PHP's header() function sets HTTP response headers. You can also set the status code with http_response_code():
Headers Must Come First
The header() function must be called before any output. PHP sends HTTP headers with the first byte of output, so even a single space or newline before <?php will cause an error.
// WRONG - whitespace before PHP tag
Content Negotiation
A single PHP endpoint can return different formats based on what the client requests via the Accept header:
For JSON APIs, form data is not available in $_POST. PHP's $_POST only works for application/x-www-form-urlencoded and multipart/form-data. For JSON bodies, you must read the raw input stream:
'Invalid JSON']);
exit;
}
// Now $data is a PHP associative array
echo "Received: " . $data['name'];
?>
Testing with curl
Use curl to send different types of requests and inspect headers:
# GET request (see response headers with -v)
curl -v http://localhost:8000/content-negotiation.php
# Request JSON via Accept header
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
Summary
$_SERVER contains all request metadata — HTTP headers become HTTP_* keys
header() sets response headers and must be called before any output
http_response_code() sets the HTTP status code
Content negotiation lets a single endpoint return JSON or HTML based on the Accept header
JSON request bodies require reading php://input since $_POST only handles form-encoded data