4

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

这很有效,而且很棒,但由于这可能是敏感数据,我不希望在为(可能)一次性下载创建文件时在服务器上挂起一堆文件。

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

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

显而易见的举动是删除文件,但我需要等到客户端先下载它,这样就很难决定何时执行。

欢迎任何建议

编码:

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

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

4

2 回答 2

7

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);

这很好用,但如果出现问题,您的用户将无法下载。

因此,如果您没有太多数据,您可以只写入内存中的流,只需交换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);
于 2013-10-20T00:14:40.660 回答
3

而不是这样,为什么不让您的页面回显csv mime 类型,然后将文件回显给用户?

它很有魅力,永远不会创建文件并将其作为一次性文件传递给客户。

像这样的东西:

header("Content-type: application/csv");
header("Content-Disposition: attachment; filename=file.csv");
header("Pragma: no-cache");
header("Expires: 0");

echo "col1,col2";
for($i=0; $i<25;$i++)
{
    echo "key :".$i.", ".($i*$i)."\r\n";
}

您应该能够按原样测试它并查看它是如何工作的。

增加的好处是大多数用户将被引导下载文件而不是打开它,因此用户甚至不会离开页面(大部分时间)。

于 2012-08-17T09:51:34.997 回答