[PHP] fputcsv関数の問題点と解決方法

PHPのfputcsv関数は便利です。
しかし、以下のような点が不便です。

エンコーディングを変換できない

主にCSV出力先になるExcelでは、Shift-JIS以外のCSVを開けません。
Excel 2007ならBOMを付けるとか、データインポートで実行するといった回避策はありますが、日本語のみならShift-JISで出力したいことが多いと思います。

このためにはあらかじめShift-JISに変換しておく必要があり、

$sjis = array_map(create_function(‘$str’, ‘return mb_convert_encoding($str, “Shift-JIS”, “UTF-8”);’), $line);

といった処理をやっていましたが、正直めんどうです。

ダブルコーテーションのエスケープにバグがある

カンマが含まれる場合、ダブルコーテーションで囲ってくれます。
ダブルコーテーションが含まれる場合、ダブルコーテーションを二重にしてエスケープしてくれます。
しかし、\" (バックスラッシュ+ダブルコーテーション)があった場合、なぜかこの部分のダブルコーテーションは二重にしてくれません。

解決方法

ということで、結局自前でやった方が便利です。

mb_str_replaceは、http://fetus.k-hsu.net/document/programming/php/mb_str_replace.htmlを使わせて頂きました。

function _fputcsv($fp, $data, $toEncoding='Shift-JIS', $srcEncoding='UTF-8') {
    require_once 'mb_str_replace.php';

    $csv = '';
    foreach ($data as $col) {
        if (is_numeric($col)) {
            $csv .= $col;
        } else {
            $col = mb_convert_encoding($col, $toEncoding, $srcEncoding);
            $col = mb_str_replace('"', '""', $col, $toEncoding);
            $csv .= '"' . $col . '"';
        }
        $csv .= ',';
    }

    fwrite($fp, $csv);
    fwrite($fp, "\r\n");
}

ちゃんとテストしていないのでミスがあるかもしれませんが、このくらいシンプルで十分そうですね。

デザインも頼めるシステム開発会社をお探しならBPS株式会社までどうぞ 開発エンジニア積極採用中です! Ruby on Rails の開発なら実績豊富なBPS

この記事の著者

baba

ゆとりプログラマー。 高校時代から趣味でプログラミングを初め、そのままコードを書き続けて現在に至る。慶應義塾大学環境情報学部(SFC)卒業。BPS設立初期に在学中から参加している最古参メンバーの一人。Ruby on Rails、PHP、Androidアプリ、Windows/Macアプリ、超縦書の開発などを気まぐれにやる。軽度の資格マニアで、情報処理技術者試験(16区分17回 + 情報処理安全確保支援士試験)、技術士(情報工学部門)、Ruby Programmer Gold、AWSソリューションアーキテクト(アソシエイト)、日商簿記2級、漢検準1級などを保有。

babaの書いた記事

週刊Railsウォッチ

インフラ

ActiveSupport探訪シリーズ