4

fputcsv()サーバー上にファイルを作成し、それを埋めてから次のページにリンクすることにより、PHPを使用してMySQLデータベースからいくつかのレコードを提供しています。

これは機能し、すばらしいですが、これは機密データである可能性があるため、(おそらく)1回限りのダウンロード用に作成されたときに、サーバー上に大量のファイルがぶら下がっているのは望ましくありません。

だから私が知りたいのはこれです:サーバーに永続的なファイルを実際に書き込むことなく、このファイルを作成してダウンロード用に提供する方法はありますか?

たとえば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ラッパーを試してみることをお勧めします

たとえば、これを実行して、CSVデータを1行ずつ「ストリーミング」することができます(さまざまな出力バッファーが適用されますが、これは別の話です)。

<?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タイプをエコーアウトさせてから、ファイルをユーザーにエコーアウトさせてはどうでしょうか。

それは魅力的に機能し、ファイルが作成されてクライアントに1つとして渡されることはありません。

このようなもの:

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 に答える