PHPでデータベースからCSVをダウンロードしよう

19/05/12 23:59:59     19/06/02 13:10:37

PHPでデータベースからCSVをダウンロードしよう

PHPにはCSVのダウンロードや出力を簡単にするための関数が用意されています。

header関数を使用する

PHPでCSVファイルをダウンロードするには、header関数を使うのが簡単です。header関数を使えばCSVファイル以外にも、いろいろな種類のファイルをダウンロードすることが可能になります。

header関数の基本的な構文は以下です。

header ($ヘッダ文字列[, $同じ名前のヘッダが指定された時に値を置換するかどうか[, $レスポンスコード]] )

まず第一引数はヘッダ文字列です。第二引数は値を置き換えるかどうかの指定を行います。第三引数はHTTPレスポンスコードを強制的に指定したい場合に使用します。

header関数の使い方は上記の通りですが、そもそもHTTPヘッダが何かという疑問が残るかもしれません。HTTPヘッダとは、データ本体から独立してブラウザやデータに関する情報を記録したものです。

具体的には、クライアント端末がサーバーにアクセスした際に、サーバーからどのようなコンテンツを返すのかを記録しているようなことです。そして、HTTPヘッダには三種類あります。

「Content-Type」「Content-Length」「Content-Disposition」の三つです。

まず一つ目のContent-Typeはダウンロードするファイルのタイプのことです。指定の仕方は簡単で、PHFなら「Content-Type: application/pdf」、JPEGなら「Content-Type: application/jpg」、CSVなら「Content-Type: application/octet-stream」となります。

CSVだけCSVと入っていないのでややこしいのですが、「octet-stream」はファイルタイプを指定しないという意味です。つまり、デフォルトでCSVになっています。

二つ目のContent-Lengthはダウンロードするファイルサイズを指定するものです。

三つ目のContent-Dispositionはファイルの処理方法を指定するもので、「Content-Disposition: attachment; filename=ファイル名」の形式になっています。

これらのHTTPヘッダを把握したうえであれば、headerの引数を指定しやすいでしょう。以上を踏まえたサンプルコードは以下です。

<?php
// ダウンロードするサーバのファイルパス
$filepath = 'sample.csv';
// HTTPヘッダを設定
header('Content-Type: application/octet-stream');
header('Content-Length: '.filesize($filepath));
header('Content-Disposition: attachment; filename=file.csv');
// ファイル出力
readfile($filepath);
?>

上での説明通り、Content-TypeはContent-Type: application/octet-streamとCSVになるようにしています。Content-Lengthはfilesize($filepath)となっていますが、これはfilesize関数を$filepathを引数にして使用しています。

Content-Dispositionはファイル名がfile.csvとなっています。その結果、file.csvという名前でダウンロードされます。

複数のファイルを圧縮してダウンロードする

上の例では単一のファイルを圧縮なしでダウンロードしましたが、次はより効率的にCSVファイルをダウンロードしていく方法です。サンプルコードは以下です。

<?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);
?>

まずZipArchiveはもともとPHPで用意されているクラスで、これを使用することでZipファイルを使用できます。クラスメソッドを作り、次にファイルパスを取得しています。

ファイルを開く際にはopenメソッドを使用し、引数にファイルパスとそれをZipにすることを指定しています。addFileメソッドではzipにしたいファイルを追加しています。

zipにするファイルを指定し終わったので、次にcloseします。次に上で説明した方法でHTTPヘッダを設定しています。Content-Typeではzipを指定しています。出力後はzipファイルを削除します。

CSVファイルの出力

CSVファイルのダウンロードについて解説しましたが、出力することも可能です。もっとも簡単な方法は、fputcsv関数を使用する方法でしょう。fputcsv関数は以下のような構文になっています。

int fputcsv ( $ファイルポインタ , array $書き込む値の配列 [, string $区切り文字 = "," [, string $フィールド囲み文字 = '"' [, string $エスケープ文字 = "\" ]]] )

これを使ったサンプルコードは以下です。

<?php
$data = [
    ['ID', '名前', '型番'],
    ['1', 'x', '30'],
    ['2', 'y', '26'],
    ['3', 'z', '32']
];

$fp = fopen('member.csv', 'w');

foreach ($data as $line) {
    fputcsv($fp, $line);
}

fclose($fp);
?>

このコードを実行すると以下のようになります。

ID,名前,型番
1,x,30
2,y,26
3,z,32

fopen関数の第二引数wは書き込みモードを意味しています。書き込みモードでファイルを開き、行数分出力し、最後にファイルをクローズしています。

まとめ

以上、PHPでCSVをダウンロードする方法と出力する方法を紹介しました。

もともと用意されているコードを使用すれば自分で新たに何か生み出すようなコーディングは不要で、関数の仕様通りに引数を指定していくだけです。

ちなみに読み込みでもだいたい同じようなコードになります。

人気記事

編集部おすすめ記事

この記事を読んだ人はこんな記事を読んでいます

案件探しやフリーランスになるための相談する