PHPでのCSVファイルの入出力方法【現役エンジニアが解説】

PROGRAM

今回は、PHPでのCSVファイルの入出力方法について、CSVファイルを読み込む方法とCSVファイルに書き出す方法に分け、簡単に解説していきます。

CSVファイルを読み込む方法

Webページのフォーム等からCSVファイルをアップロードし、PHPでデータを読み込むことはよくあることです。

以下のサンプルコードは、そのようにアップロードされたCSVファイルを読み込み、UTF-8のエンコードで処理することを想定したコードとなります。

$buffer = file_get_contents($_FILES['name']['tmp_name']); // 'name'はフォームデータのname属性
// $buffer = mb_convert_encoding($buffer, "UTF-8", "sjis-win"); // CSVファイルのエンコードがShift-JISの場合に変換
$fp = tmpfile();
fwrite($fp, $buffer);
rewind($fp);
while ( ($row = fgetcsv($fp)) !== false) {
    // $rowを使って各行の処理を書く
}

上記コードでは、CSVファイルのエンコードがUTF-8である前提ですが、mb_convert_encoding関数を使用することでShift-JISのCSVファイルでも取り扱いが可能になります。

CSVファイルにデータを書き出す方法

CSVファイルを読み込むことが多々ある一方で、逆にデータをCSVファイルに書き出すこともあると思います。

以下のサンプルコードは、PHPの連想配列の配列や配列の配列のデータをCSVファイルに書き出すコードとなります。

$filename = "hoge.csv"; // CSVファイルの名前
$filedata = array(); // 連想配列の配列や配列の配列
header("Content-Type: application/octet-stream; charset=utf-8");
header("Content-Disposition: attachment; filename=".$filename."; filename*=UTF-8''".rawurlencode($filename));
$file = fopen('php://output', "w" );
// fwrite($file, "\xEF\xBB\xBF"); // BOM付きにさせる場合にファイルの先頭に書き込む
foreach($filedata as $row) {
    fputcsv($file, $row); // 配列の各要素をCSVにしていく
}
fclose($file);

ただし、上記のコードでは、UTF-8のエンコードでCSVファイルに書き出していますので、Excelで表示させたい場合には、BOM付きにしましょう。

データのエンコードをShift-JISにしてCSVファイルに書き出す方法

Excelで編集を行いたい場合等、CSVファイルにデータを書き出す際にエンコードをShift-JISにしたいこともあります。

以下のサンプルコードは、ファイル名のエンコードをUTF-8で、データの中身のエンコードをUTF-8にしてCSVファイルに書き出すコードとなります。

$filename = "hoge.csv"; // CSVファイルの名前
$filedata = array(); // 連想配列や配列の配列
header("Content-Type: application/octet-stream; charset=Shift_JIS");
header("Content-Disposition: attachment; filename=".$filename."; filename*=UTF-8''".rawurlencode($filename));
$file = fopen('php://output', "w" );
stream_filter_prepend($file,'convert.iconv.utf-8/cp932');
stream_filter_register('crlf', 'crlf_filter');
stream_filter_append($file, 'crlf');
foreach($filedata as $row) {
    fputcsv($file, $row); // 配列の各要素をCSVにしていく
}
fclose($file);

PHPを使ったWebアプリケーションのほとんどのエンコードはUTF-8ですが、ユーザはOfficeを多用するため、エンコードはShift-JISで希望されることが多い印象です。