我正在寻找一种简单的方法,将一个数组转换为CSV,并使用户能够下载CSV文件,而不需要将CSV文件保存到服务器上。
$array = [
['name', 'email'],
['Doe, John', 'johndoe@foo'],
['Jane Doe', 'janedoe@foo'],
['Ron "SuperFly" O\'Neal', 'supafly@foo'],
];
header("Content-type: application/csv");
header("Content-Disposition: attachment; filename=test.csv");
$fp = fopen('php://output', 'w'); // or use php://stdout
foreach ($array as $row) {
fputcsv($fp, $row);
}
使用fputcsv()
的好处在于它会自动处理字段的转义和封闭,确保输出的有效、稳固,即使列值包含CSV控制字符,例如逗号、引号、换行符等,也不会破坏输出。如果您没有恰当地处理控制字符,而是采用了常见的捷径,例如使用implode(',', $row)
,您的(低质量)代码将生成破损的CSV输出。
遗憾的是,fputcsv()
不能直接输出到字符串,只能输出到流中,因此我通过php://output
向php的输出流写入,相当于使用echo
输出。请注意,就像通过echo
输出一样,它将通过php的输出缓冲机制,并且包括任何可能的输出处理程序,例如ob_gzhandler
或可能修改输出的客户端输出缓冲器回调函数。如果您想绕过输出缓冲区,可以直接写入php://stdout
。
如果需要在输出之前以字符串形式访问csv文件内容,还可以将其写入php://memory
、php://temp
或文件中。
$fp = fopen('php://memory', 'w+'); // or php://temp
foreach ($array as $row) {
fputcsv($fp, $row);
}
// Read it back into a string, if desired.
// Rewind the stream to start.
fseek($fp, 0);
// Read the entire stream back to string.
$csvContents = stream_get_contents($fp);
header("Content-type: application/csv");
header("Content-Disposition: attachment; filename=test.csv");
header("Pragma: no-cache");
header("Expires: 0");
echo "name,city,street\n";
标签
。header("Content-Type: application/octet-stream");
for IE...