###前提・実現したいこと
5万件以上のデータをCSVダウンロードしようとすると、メモリ不足になってしまいます。
プログラミングの記述方法に問題がありますか?
※3万件のデータはダウンロードできるので、メモリ不足と判断しています。
###該当のソースコード
/config/myconf/csvExport/Hoges.php
PHP
1$header = ['ID::id', '会社名::name']; 2 3 $this->response->body(fputcsv($fp,$header)); 4 5 foreach ($query as $data) { 6 $data = [ 7 $data['id'], 8 $data['name'] 9 ]; 10 $this->response->body(fputcsv($fp, $data)); 11 }
/src/Controller/HogesController.php
PHP
1public function export($query) 2 { 3 $this->autoRender = false; 4 5 stream_filter_register('eolFilter', 'App\\Filters\\CsvEolFilterHelper'); 6 stream_filter_register('encodeFilter', 'App\\Filters\\CsvEncodeFilterHelper'); 7 8 $fp = fopen('php://output', 'w'); 9 10 // フィルタを開いたストリームに付加する 11 stream_filter_append($fp, 'eolFilter'); 12 stream_filter_append($fp, 'encodeFilter'); 13 14 // ダウンロードさせる 15 header('Content-Type: text/csv'); 16 header('Content-Disposition: attachment; filename="テスト.csv"'); 17 18 include ('../config/myconf/csvExport/Hoges.php'); 19 20 fclose($fp); 21 }
/src/Filters/CsvEncodeFilterHelper.php
PHP
1namespace App\Filters; 2 3// 文字コードをUTF-8からShift-JISに置換するフィルタ 4class CsvEncodeFilterHelper extends \php_user_filter { 5 function filter($in, $out, &$consumed, $closing) { 6 while ($bucket = stream_bucket_make_writeable($in)) { 7 $bucket->data = mb_convert_encoding($bucket->data, 'SJIS-win', 'UTF-8'); 8 $consumed += $bucket->datalen; 9 stream_bucket_append($out, $bucket); 10 } 11 return PSFS_PASS_ON; 12 } 13}
/src/Filters/CsvEolFilterHelper.php
PHP
1namespace App\Filters; 2 3// 改行コードをPHP_EOLからCR+LFに置換するフィルタ 4class CsvEolFilterHelper extends \php_user_filter { 5 function filter($in, $out, &$consumed, $closing) { 6 while ($bucket = stream_bucket_make_writeable($in)) { 7 $bucket->data = str_replace(PHP_EOL, "\r\n", $bucket->data); 8 $consumed += $bucket->datalen; 9 stream_bucket_append($out, $bucket); 10 } 11 return PSFS_PASS_ON; 12 } 13}
###備考
以前の質問
https://teratail.com/questions/78597

回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/06/02 05:37
2017/06/02 07:39