如何将输出作为文件提供而不将其保存在服务器上

tot*_*rds 4 php csv export-to-csv

fputcsv()通过在服务器上创建文件,填充它,然后在下一页链接到它,使用PHP从MySQL数据库中提供一些记录.

这很有用,但是因为这可能是敏感数据,所以我不希望在为(可能)一次性下载创建文件时挂起一大堆文件.

所以我想知道的是:有没有办法创建这个文件并提供下载服务,而无需在服务器上实际写入永久文件?

例如,我可以创建一个逗号分隔的字符串而不是使用fputcsv()并在输出缓冲区中使用正确的标头来提供它吗?

显而易见的举措是删除文件,但我需要等到客户端先下载它,这样才能决定何时进行操作.

欢迎任何建议

代码:

$fp = fopen($filename, 'w');
fputcsv($fp, array("Last Name", "First Name"));
foreach ($result as $fields) 
{
    fputcsv($fp, $fields);
}
fclose($fp);
Run Code Online (Sandbox Code Playgroud)

http://php.net/manual/en/function.fputcsv.php

tim*_*dev 6

fputcsv()是一个神话般的小功能,所以我不会放弃它.

相反,我建议您使用PHP的内置I/O Wrappers

例如,您可以这样做,逐行"流式传输"您的CSV数据(受各种输出缓冲区限制,但这是另一个故事):

<?php
header('Content-type: text/csv; charset=UTF-8');
header('Content-disposition: attachment; filename=report.csv');
$fp = fopen('php://output','w');
foreach($arrays as $array) fputcsv($fp, $array);
Run Code Online (Sandbox Code Playgroud)

这很好用,但如果出现问题,您的用户将有一个损坏的下载.

所以,如果你没有太多的数据,你可以只写一个内存流,只是换出php://outputphp://memory和移动的东西:

<?php
$fp = fopen('php://memory','rw');

// our generateData() function might throw an exception, in which case 
// we want to fail gracefully, not send the user a broken/incomplete csv.
try {
    while($row = generateData()) fputcsv($fp, $row);
}catch(\Exception $e){
    // display a nice page to your user and exit/return
}

// SUCCESS! - so now we have CSV data in memory.  Almost like we'd spooled it to a file
//            on disk, but we didn't touch the disk.

//rewind our file handle
rewind($fp);

//send output
header('Content-type: text/csv; charset=UTF-8');
header('Content-disposition: attachment; filename=report.csv');
stream_get_contents($fp);
Run Code Online (Sandbox Code Playgroud)