Current Location: Home> Latest Articles> Use header() to simulate the scenario of downloading CSV reports

Use header() to simulate the scenario of downloading CSV reports

M66 2025-05-18

In web development, sometimes we need to dynamically generate a CSV report through the backend and provide it to users to download, instead of putting it on the server for download. PHP's header() function can be used to modify the HTTP response header and combine it with the output content to achieve this "simulated download" effect.

This article will take you to implement this function step by step.

Step 1: Prepare CSV data

First, we need to have a copy of the CSV data to be output. It can be extracted from the database or it can be a manually prepared array.

 $data = [
    ['Name', 'Mail', 'Registration time'],
    ['Zhang San', 'zhangsan@m66.net', '2025-05-01 10:00:00'],
    ['Li Si', 'lisi@m66.net', '2025-05-02 11:30:00'],
    ['Wang Wu', 'wangwu@m66.net', '2025-05-03 14:15:00'],
];

Step 2: Set up the HTTP header

Use the header() function to tell the browser that this is a file download response, not a normal web page output. What is particularly important is:

  • Content-Type tells the browser that this is a CSV file;

  • Content-Disposition sets the attachment form and provides the name of the downloaded file;

  • Cache-Control and Pragma help avoid caching issues.

 header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename="report.csv"');
header('Cache-Control: no-cache, no-store, must-revalidate');
header('Pragma: no-cache');
header('Expires: 0');

Step 3: Output CSV content

You can use fopen('php://output', 'w') to write the content directly to the output stream, and there is no need to generate an intermediate file.

 $output = fopen('php://output', 'w');

foreach ($data as $row) {
    fputcsv($output, $row);
}

fclose($output);

Complete sample code

 <?php
$data = [
    ['Name', 'Mail', 'Registration time'],
    ['Zhang San', 'zhangsan@m66.net', '2025-05-01 10:00:00'],
    ['Li Si', 'lisi@m66.net', '2025-05-02 11:30:00'],
    ['Wang Wu', 'wangwu@m66.net', '2025-05-03 14:15:00'],
];

header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename="report.csv"');
header('Cache-Control: no-cache, no-store, must-revalidate');
header('Pragma: no-cache');
header('Expires: 0');

$output = fopen('php://output', 'w');

foreach ($data as $row) {
    fputcsv($output, $row);
}

fclose($output);

Things to note

  1. Don't have extra output <br> Before calling header() , there cannot be any unnecessary output (including spaces, line breaks, BOM), otherwise it will cause a "Headers already sent" error.

  2. Coding issues <br> If the generated CSV contains Chinese characters, it is best to use UTF-8 BOM or convert it to GBK to avoid garbled code when opening in Excel.

  3. Dynamic data <br> The above example uses static arrays. In actual projects, you often need to query from the database and then spell it into an array.