Skip to Content
Course content

82: Working with HTTP Headers in PHP

Click on the "Edit" button in the top corner of the screen to edit your slide content.

I once worked with a junior developer who spent an entire afternoon convinced that our server was randomly failing. He was trying to redirect a user to a login page after a session timeout, but the redirect simply wouldn't trigger. He had checked the logic five times, and it was flawless. The culprit? A single, invisible whitespace character sitting outside the opening <?php tag at the very top of his file. That tiny space counted as "output," and in the world of HTTP, once you've sent even one byte of content to the browser, the window for sending headers slams shut.

HTTP headers are the "metadata" of the web. They are the instructions the server sends to the browser before the actual HTML or JSON payload arrives. They tell the browser what kind of data to expect, whether it should cache the page, or if it should immediately go somewhere else entirely. In PHP, we handle this primarily through the header() function.

Directing the Browser's Flow

The most common use case you'll encounter is the Location header, which triggers a redirect. If you've just processed a form and want to send the user to a "Thank You" page, this is how you do it. However, there is a critical detail most tutorials gloss over: you must call exit() or die() immediately after the header.

If you don't call exit(), PHP will keep executing the rest of the script. A malicious user or a clever bot could ignore the redirect header and see the content below it, which might include sensitive data you thought was hidden by the redirect.

Defining the Content Type

By default, PHP sends Content-Type: text/html. This is fine for standard pages, but what happens when you're building an API or generating a file? If you're returning data for a JavaScript fetch() call, you need to tell the browser it's looking at JSON, not HTML. Otherwise, the browser might try to render your JSON string as a webpage, or your frontend framework might struggle to parse it.

 'success', 'user_id' => 42];
header('Content-Type: application/json; charset=utf-8');
echo json_encode($data);
?>

I've also used this for generating dynamic images or PDFs. By changing the header to image/png or application/pdf, you change how the browser interprets the raw binary data following the header.

Avoiding the 'Headers Already Sent' Trap

As I mentioned in my opening story, the header() function only works if no output has been sent to the browser yet. This includes echo statements, print_r, or even HTML outside of your PHP tags. If you see the error "Cannot modify header information - headers already sent", your first instinct should be to look for output that happened too early.

If you find yourself in a complex architecture where you absolutely cannot avoid early output—perhaps because of a legacy include file—you can use Output Buffering. By calling ob_start() at the very top of your script, PHP holds all output in an internal buffer. This lets you call header() anywhere in your code, and PHP will simply flush the buffer and the headers to the browser all at once at the end of the execution.




📋 Practical Task

Exercise: Creating a Forced CSV Download Trigger

Your goal is to create a PHP script that doesn't just display text on the screen, but forces the browser to download a file named report.csv.

Requirements:

  • Create a script that defines a small array of data (e.g., a list of usernames and emails).
  • Use the header() function to set the Content-Type to text/csv.
  • Use the Content-Disposition header to force the browser to trigger a "Save As" dialog with the filename report.csv.
  • Loop through your array and echo the data in CSV format (comma-separated values).
  • Ensure there is absolutely no HTML or whitespace outside of your PHP tags to avoid the "headers already sent" error.
Rating
0 0

There are no comments for now.

to be the first to leave a comment.