PHPでCSV出力。ダウンロードせず文字化けしてブラウザで表示される。
久しぶりにCSV出力を実装したときの覚書。
環境: nginx 1.20.1, PHP 7.4.6
CSVでダウンロードするように実装した後、データが多くなると文字化けしてダウンロードまでいかない現象が発生。
参考サイト
- php://outputが書き込みの途中で出力される - Qiita
※ コメントを読むこと
ポイントは
- fputcsv前にheader関数を使いHTTPヘッダーを送信(設定)する。
参考: PHP: header - Manual output_bufferingを十分な値に設定する。
参考: PHP: 実行時設定 - Manual- 【追記】output_bufferingを使わずにtempnamで一時ファイルを生成してダウンロードするべき。
参考: PHP: tempnam - Manual
output_bufferingの詳細
output_bufferingは出力するための作業領域容量を設定する。
生成するCSVファイルが大きくなる可能性がある場合は、実ファイルとして保存する処理に変更する。
そもそも出力バッファを使わずに実ファイルとして生成→readfile→unlinkするべき。
ファイル名は他の処理と被らないようにランダム生成。
tempnamという関数を使うと簡単に実装可能。
参考: PHP: tempnam - Manual
どうしても出力バッファを使いたい場合はoutput_bufferingの設定を変更する。
# less /etc/php.ini
output_buffering = 40960
再読み込み
# systemctl reload php-fpm
ちなみにPHP CLIは常にoutput_bufferingが0なのでコマンドで確認しても常に0。
# php -i | grep output
ブラウザでphpinfo()を確認する必要がある。