PHPで配列からCSVを吐きだそうとして、なぜか非常にテンパったのでメモ。ファイルをテンポラリとして使うのは何だかなーと思ったので、ストリームでCSVを出力してみました。久々にPHPをいじると嵌りまくって時間を使っちゃったのでメモです。久々だと忘れているもんですね。
PHPからCSV出力が必要だった訳
CSVを直接ダウンロードしたいなんかの要件ってよくありますよね。データベースの出力をそのままCSVで出力してあげるAPIだとかそんな感じのです。
今回、Wordpressの「WordPress Charts and Graphs Lite」を利用する機会があったので、データを直接生成することに。CSVのURLを書いておくとプラグイン上でファイルをアップロードしなくていいので楽なのです。データベースと連携させると動的な物も作れるかなーと行った次第です。
てことで、実際のコードを見ていきます。
実際のコード
何の変哲もないPHPコードです。なんではまったんだろう?
//何かしらの配列 $csv = array( array("date","apple","orange","lemon","grape"), array("2019-01-24","120","200","200","120"), array("2019-01-25","118","150","168","115"), array("2019-01-26","117","145","170","98") ); //ヘッダー header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename=data.csv'); //そのまま出力 foreach ($csv as $line) fputcsv(fopen('php://output', 'w'), $line);
出力結果
date,apple,orange,lemon,grape 2019-01-24,120,200,200,120 2019-01-25,118,150,168,115 2019-01-26,117,145,170,98
見事に出力できています!
ポイント
ポイントは fopen(‘php://output’, ‘w’) の使い方でしょうか。
マニュアルには、
php://output は書き込み専用のストリームで、 print および echo と同じ方法での出力バッファへの書き込みを許可します。
よくわかりませんが、とりあえず php://output を使うことでファイルをわざわざオープンすることなく、ストリームを垂れ流ししてくれるみたいです。
一次ファイルを作ると、ファイルを消す処理だったりとかファイルロックの問題があったりとかで、サーバーに負荷をかけてしまうので、直接出力する系の処理はこれで決まりです。
これで、データベースから直接CSVを吐きだして、WordPress Charts and Graphs Lite にぶち込めるので一件落着です。