こんにちは!フリーエンジニアのせきです。
PHPではサーバにCSVファイルを出力したり、サーバ上のCSVファイルをブラウザからダウンロードすることができます。
この記事では、
・CSVファイルを出力する方法が知りたい
・CSVファイルを読み込む方法が知りたい
・CSVファイルをダウンロードする方法が知りたい
という基本的な内容から、
・複数のファイルを圧縮してダウンロードする方法が知りたい
といった応用的な内容に関しても解説していきます。
今回はそんなCSVファイルを出力、ダウンロードする方法について、わかりやすく解説します!
CSVファイルを出力する方法
ここでは、fputcsv関数とSplFileObjectクラスを使用して、CSVファイルにデータを出力する方法を紹介します。
CSVファイルはカンマ(,)区切りでデータが格納されているファイルで、拡張子は.csvとなります。
手軽にデータを扱えることからさまざまなプログラムで使用されています。
fputcsv関数とは
PHPでCSV形式のデータをファイルに出力するには、fputcsv関数を使用します。
書き方:
int fputcsv ( $ファイルポインタ , array $書き込む値の配列 [, string $区切り文字 = "," [, string $フィールド囲み文字 = '"' [, string $エスケープ文字 = "\" ]]] )
引数:
第一引数にはファイルポインタを指定します。ファイルポインタはあらかじめfopen関数などで正常にオープンされたファイルを指定する必要があります。
第二引数には書き込む値を配列で指定します。
第三引数には区切り文字、第四引数にはフィールド囲い込み文字、第五引数にはエスケープ文字を指定します。
戻り値:
書き込んだ文字列の長さを返します。失敗した場合はFALSEを返します。
サンプルプログラム:
<?php $data = [ ['ID', '名前', '年齢'], ['1', '田中', '30'], ['2', '小林', '26'], ['3', '江口', '32'] ]; $fp = fopen('member.csv', 'w'); foreach ($data as $line) { fputcsv($fp, $line); } fclose($fp); ?>
実行結果:
member.csv
ID,名前,年齢 1,田中,30 2,小林,26 3,江口,32
$dataが書き込む値の配列です。
fopen関数を使用し、’member.csv’を書き込みモード’w’でオープンします。
配列をひとつずつfputcsv関数に渡し、member.csvに書き込みます。
最後にfclose関数でファイルをクローズします。
SplFileObjectクラスとは
SplFileObjectクラスのfputcsvメソッドを使用して、CSVファイルを出力することもできます。
SplFileObjectクラスは、ファイル操作を行うためのさまざまなインターフェイスを提供するクラスです。
書き方:
$file = new SplFileObject( $ファイル名, 'w' ); $file->fputcsv($書き込む値の配列);
サンプルプログラム:
<?php $data = [ ['ID', '名前', '年齢'], ['1', '田中', '30'], ['2', '小林', '26'], ['3', '江口', '32'] ]; $file = new SplFileObject('member.csv', 'w'); foreach ($data as $line) { $file->fputcsv($line); } ?>
実行結果:
member.csv
ID,名前,年齢 1,田中,30 2,小林,26 3,江口,32
サンプルではファイル名’member.csv’を指定し、SplFileObjectクラスのオブジェクトを生成しています。
そのfputcsvメソッドに配列をひとつずつ渡し、member.csvに書き込みます。
CSVファイルを読み込む方法
既に作成されているCSVファイルを読み込むには、fgetcsv関数を使用します。
fgetcsv関数はCSVファイルに記述されたデータを1行ずつ読み込んで、値を取得することができます。
そんなCSVファイルの読み込み方法については、以下の記事で詳しく解説しています!
CSVファイルをダウンロードする方法
CSVファイルをダウンロードするには、header関数を使用してレスポンスにダウンロード用のHTTPヘッダを設定し、ファイルを出力します。
この方法はCSVファイルに限らず、テキストファイルや画像ファイルなど様々なファイルタイプで使用できます。
HTTPヘッダ
HTTPヘッダとは、サーバへのリクエスト時にはどんなブラウザがどういった情報をリクエストしているのか、サーバからのレスポンス時にはどのようなコンテンツを返すのかといった、データ本体とは別にブラウザやデータに関する情報を付加するものです。
ダウンロードのために設定するHTTPヘッダは以下の3つです。
-
1.Content-Type
ダウンロードするファイルのタイプを指定します。
PDFファイルであれば「Content-Type: application/pdf」、JPGファイルであれば「Content-Type: application/jpg」のような形式で指定します。
CSVファイルをダウンロードする場合は、Content-Typeで「Content-Type: application/octet-stream」を指定します。
「octet-stream」は、ファイルタイプを特に意識する必要のない時に使用する形式です。
-
2.Content-Length
ダウンロードするファイルのサイズを指定します。
指定することで、ダウンロードの進捗状況が表示されます。
-
3.Content-Disposition
ファイルの処理方法を指定します。
「Content-Disposition: attachment; filename=ファイル名」と指定すると、多くのブラウザは指定したファイル名でファイルを保存するダイアログを表示します。
headerの基本的な使い方
HTTPヘッダは、以下のように設定します。
書き方:
header ($ヘッダ文字列[, $同じ名前のヘッダが指定された時に値を置換するかどうか[, $レスポンスコード]] )
引数:
第一引数に送信するヘッダ文字列を指定します。
第二引数は、「Content-Type: application/pdf」「Content-Type: application/jpg」のように、同じ名前(この場合「Content-Type」)のヘッダが指定された場合に、値を置き換えるかどうかを指定します。デフォルトはtrueで置き換えられますが、falseを指定すると両方の値を送ろうとします。
第三引数は、HTTPレスポンスコードを強制的に指定したい場合に使用します。
ファイルダウンロード
ファイルをダウンロードするサンプルです。
サンプルプログラム:
<?php // ダウンロードするサーバのファイルパス $filepath = 'sample.csv'; // HTTPヘッダを設定 header('Content-Type: application/octet-stream'); header('Content-Length: '.filesize($filepath)); header('Content-Disposition: attachment; filename=download.csv'); // ファイル出力 readfile($filepath); ?>
「$filepath」は、ダウンロードするサーバのファイルパスです。ファイルサイズの取得とファイル出力時に使用します。
ファイルパスは絶対パスでも相対パスでも指定することができます。
次にheader関数でHTTPヘッダを設定します。
「Content-Type」は、CSVファイルをダウンロードするので「Content-Type: application/octet-stream」を指定しています。
「Content-Length」は、ファイルサイズを取得するfilesize関数を使用し指定しています。
「Content-Disposition」は、「download.csv」というファイル名でダウンロードされるよう指定しています。
最後に、readfile関数でファイル出力しています。
実行すると、以下のようなダイアログが表示されます。
(これはFireFoxで実行した例です。)
複数のファイルを圧縮してダウンロードする方法
複数のファイルをZipで圧縮して1つのファイルにまとめ、ダウンロードをすることができます。
以下にサンプルを示します。
サンプルプログラム:
<?php // ZipArchiveクラス初期化 $zip = new ZipArchive(); // Zipファイルパス $zipFilepath = './sample.zip'; // Zipファイルオープン $zip->open($zipFilepath, ZIPARCHIVE::CREATE); // ファイル追加 $zip->addFile('csv1.csv'); $zip->addFile('csv2.csv'); $zip->addFile('csv3.csv'); // Zipファイルクローズ $zip->close(); // HTTPヘッダを設定 header('Content-Type: application/zip'); header('Content-Length: '.filesize($zipFilepath)); header('Content-Disposition: attachment; filename=images.zip'); // ファイル出力 readfile($zipFilepath); // Zipファイル削除 unlink($zipFilepath); ?>
Zipファイルを扱うには、ZipArchiveクラスを使用します。
「$zip = new ZipArchive();」でZipArchiveクラスを初期化します。
openメソッドに、作成するZipファイルのパスと「ZIPARCHIVE::CREATE」を指定することで、新規にZipファイルを作成します。
addFileメソッドで、Zipファイルにファイルを追加することができます。
これでダウンロードするZipファイルができるので、closeメソッドでクローズします。
ダウンロードの処理は、他のファイルタイプと同様です。
Content-TypeはZipファイルなので「Content-Type: application/zip」を指定します。
readfileでファイルを出力します。
作成したZipファイルは不要なので、unlink関数を使用し、最後に削除しています。
ファイル操作についてもっと詳しく知りたい方へ
ファイルのさまざまな使い方については、以下の記事にまとめていますので、ぜひ参考にしてくださいね!
<解説している内容>
・ファイルを読み込む方法
・ファイルに書き込む方法
・ファイルをダウンロードする方法
・ファイルを削除する方法
・CSVファイルを読み込む方法
・ファイルの内容を全て読み込む方法
・外部ファイルを読み込む方法
・ファイル・ディレクトリを調べる方法
まとめ
今回はCSVファイルに関して、
- CSVファイルを出力する方法
- CSVファイルを読み込む方法
- CSVファイルをダウンロードする方法
について解説しました。
手順を覚えてしまえば簡単に出力やダウンロードすることができますので、やり方をしっかりと覚えましょう。
CSVファイルを出力、ダウンロードする方法を忘れてしまったら、この記事を思い出して下さい!