【问题标题】:Create CSV in memory, email, and remove from memory在内存、电子邮件中创建 CSV 并从内存中删除
【发布时间】:2015-08-11 05:16:47
【问题描述】:
private function convert_to_csv($input_array, $output_file_name, $delimiter) {

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

    foreach ($input_array as $line) {

        fputcsv($temp_memory, $line, $delimiter);

    }

    fseek($temp_memory, 0);

    header('Content-Type: application/csv');
    header('Content-Disposition: attachement; filename="' . $output_file_name . '";');

    fpassthru($temp_memory);

}               

我使用上面的函数来获取一个数据数组,转换为 CSV,然后输出到浏览器。两个问题:

  1. 通过 HTTP 下载后文件是否从内存中删除?
  2. 如何重写相同的函数,以便文件可以使用(例如,用作通过 PHPMailer 发送的电子邮件附件),然后立即从内存中删除?

编辑:工作代码 - 但写入文件,而不是内存

public function emailCSVTest() {

    $test_array = array(array('Stuff','Yep'),array('More Stuff','Yep yep'));

    $temp_file = '/tmp/temptest.csv';

    $this->convertToCSV($test_array, $temp_file);

    $this->sendUserEmail('Test Subject','Test Message','nowhere@bigfurryblackhole.com',$temp_file);

    unlink($temp_file);

}

private function convertToCSV($input_array, $output_file) {

    $temp_file = fopen($output_file,'w');

    foreach ($input_array as $line) {

        fputcsv($temp_file, $line, ',');

    }

    fclose($temp_file);

}

仍然没有答案:原始函数是否会从内存中删除文件?

【问题讨论】:

  • 我只需将文件存储在文件系统上(例如/tmp),发送邮件(带附件),然后在文件名上调用unlink()
  • 因此将第一行更改为 $temp_file = fopen('/tmp/abc.csv','w'),创建文件,然后将 fseek >> fpassthru 替换为 return $temp_file,跟进带有 unlink($temp_file) 的父函数?
  • 类似的东西,是的。不要忘记先fclose() 文件。 (在unlink() 之前)
  • 谢谢!上面添加了工作示例。
  • 如果您需要它是易失性的,为什么您首先要写入文件?

标签: php file memory


【解决方案1】:

我会像这样使用 PHP 的 temp fopen 包装器和内存阈值:

// we use a threshold of 1 MB (1024 * 1024), it's just an example
$fd = fopen('php://temp/maxmemory:1048576', 'w');
if ($fd === false) {
    die('Failed to open temporary file');
}

$headers = array('id', 'name', 'age', 'species');
$records = array(
    array('1', 'gise', '4', 'cat'),
    array('2', 'hek2mgl', '36', 'human')
);

fputcsv($fd, $headers);
foreach($records as $record) {
    fputcsv($fd, $record);
}

rewind($fd);
$csv = stream_get_contents($fd);
fclose($fd); // releases the memory (or tempfile)

内存阈值为 1MB。如果 CSV 文件变大,PHP 会创建一个临时文件,否则一切都将发生在内存中。优点是大的CSV 文件不会耗尽内存。

关于第二个问题,fclose()会释放内存。

我曾经写过一篇关于这个的博客文章,你可能会觉得很有趣:http://www.metashock.de/2014/02/create-csv-file-in-memory-php/

【讨论】:

  • 当另一个进程(用户)运行相同的脚本并且还必须创建临时文件时会发生什么:每个临时文件都有唯一的文件名吗?这样它们就不会被覆盖?
  • 当然,这很安全。
  • 如果我需要 'file_path' 用于其他函数(例如 CurlFile()),那么路径将是整个 'php://temp/maxmemory:1048576' ?跨度>
  • 不,这会打开一个新文件。您需要传递文件描述符$fd。看起来这不适用于CurlFile()。这个功能是如何设计的,真是可悲。我建议提交一个功能请求以支持文件名或文件描述符(我知道这对你 atm 没有帮助)..
  • 如果我创建临时文件(不在内存文件中)并获取该临时文件的文件路径,那么它可能会与 CurlFile() 一起使用?然后我需要获取该临时文件的路径...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-08
  • 1970-01-01
  • 2013-09-01
  • 2023-03-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多