fputcsv()
The fputcsv() function is a built-in PHP function that formats an array as a comma-separated values (CSV) line and writes it to a file. This function is used to
The fputcsv() function formats a single row of data — given as a PHP array — into a CSV (comma-separated values) line and writes it to an open file. It is the standard way to export tabular data such as reports, database exports, or spreadsheets that users will open in Excel, Google Sheets, or LibreOffice.
This page covers the syntax and parameters, the typical write loop, how fputcsv() quotes and escapes special characters automatically, how to control the delimiter and enclosure, and the most common gotchas (the trailing newline, UTF-8 in Excel, and the changing default for the $escape parameter).
Syntax
fputcsv(
resource $stream,
array $fields,
string $separator = ",",
string $enclosure = "\"",
string $escape = "\\",
string $eol = "\n"
): int|false| Parameter | Description |
|---|---|
$stream | An open file pointer returned by fopen(), in a mode that allows writing ('w', 'a', 'w+', etc.). |
$fields | The array of values that make up one CSV row. |
$separator | The field delimiter — one single-byte character. Default is a comma (,). |
$enclosure | The character used to wrap a field when it contains a separator, newline, or the enclosure itself. Default is a double quote ("). |
$escape | The escape character. Default is a backslash (\). Passing "" disables the proprietary escaping (recommended for RFC 4180 compatibility). |
$eol | The end-of-line sequence appended after the row. Added in PHP 8.1. |
Return value: the number of bytes written, or false on failure.
The
$eolparameter is available from PHP 8.1, and PHP 9.0 changes the default value of$escapefrom"\\"to"". If you want stable, portable output today, passescape: ""explicitly.
How fputcsv() Works
fputcsv() takes one array and writes exactly one line. To export a table you call it once per row inside a loop. The function handles quoting for you: any field that contains the separator, the enclosure, or a newline is automatically wrapped in the enclosure character, and embedded quotes are doubled.
The basic workflow is:
- Build an array (or array of arrays) holding the data to export.
- Open the target file for writing with
fopen(). - Call
fputcsv()once per row. - Close the file with
fclose().
Basic Example: Writing a CSV File
<?php
$data = [
['Name', 'Surname', 'Age', 'Gender'], // header row
['John', 'Doe', '30', 'Male'],
['Jane', 'Doe', '25', 'Female'],
['Bob', 'Smith', '40', 'Male'],
];
$file = fopen('people.csv', 'w');
foreach ($data as $row) {
fputcsv($file, $row);
}
fclose($file);
// Show what was written:
echo file_get_contents('people.csv');Output:
Name,Surname,Age,Gender
John,Doe,30,Male
Jane,Doe,25,Female
Bob,Smith,40,MaleThe first array is written as a header row, then each subsequent array becomes one data line.
Automatic Quoting and Escaping
You don't quote fields yourself — fputcsv() decides when quoting is required. A field is enclosed only if it contains the delimiter, a line break, or the enclosure character.
<?php
$file = fopen('php://output', 'w'); // write straight to the browser/CLI
fputcsv($file, ['Plain', 'Has, comma', 'Has "quotes"', "Two\nlines"]);
fclose($file);Output:
Plain,"Has, comma","Has ""quotes""","Two
lines"Notice that Plain is left as-is, the comma-containing field is wrapped in quotes, the embedded double quotes are doubled (""), and the value with a newline is enclosed so the line break survives. The php://output stream is handy for testing or for streaming a download without a temporary file.
Custom Delimiter and Enclosure
To produce a tab-separated or semicolon-separated file, pass the $separator argument. Many European locales open semicolon-delimited files more cleanly in Excel.
<?php
$file = fopen('php://output', 'w');
// Semicolon delimiter
fputcsv($file, ['John', 'Doe', '30'], ';');
// Tab delimiter
fputcsv($file, ['Jane', 'Doe', '25'], "\t");
fclose($file);Output:
John;Doe;30
Jane Doe 25Common Gotchas
- Trailing newline.
fputcsv()always appends a line ending, so the file ends with a blank line. When you later read it withfgetcsv()this is harmless, but it can surprise byte-exact comparisons. - UTF-8 in Excel. Excel needs a UTF-8 BOM to render accented characters correctly. Write one before the first row:
fwrite($file, "\xEF\xBB\xBF");. Seefwrite(). - The
$escapeparameter. The legacy backslash escaping can corrupt fields that legitimately contain\. Passescape: ""(PHP 7.4+) for clean RFC 4180 output; this also matches PHP 9's new default. - Always check the return value.
fputcsv()returnsfalseon failure (for example, a disk-full or read-only stream). Wrap writes in error handling for production exports. - Convenience alternative. To dump an entire string to a file in one call, see
file_put_contents(); usefputcsv()when you need proper CSV escaping per row.
Reading the File Back
The natural counterpart of fputcsv() is fgetcsv(), which parses one CSV line back into an array:
<?php
$file = fopen('people.csv', 'r');
while (($row = fgetcsv($file)) !== false) {
echo implode(' | ', $row), PHP_EOL;
}
fclose($file);If you have a CSV string already in memory rather than a file, use str_getcsv() instead.
Conclusion
fputcsv() is the idiomatic way to export array data to CSV in PHP: it handles delimiter quoting and quote escaping automatically, supports custom separators, and pairs naturally with fopen() and fclose(). For portable output, pass escape: "", and add a UTF-8 BOM when the file is destined for Excel. To read the data back, reach for fgetcsv().