UTF-8環境下でShift-JISのCSVファイルを読み込んでハッシュ配列に格納する関数

サイトの移行やリニューアルのさいには、CSVファイルからサイトのコンテンツを読み込む場合が多々あると思います。

例えば、エクセルで管理している店舗データや商品データ、会員データなどを新しいシステムにインポートする場合がそうです。

そのさい、CSVファイルを読み込んで、
$data[1行目][‘項目名1’]=”値1-1″、$data[1行目][‘項目名2’]=”値1-2″…
$data[2行目][‘項目名1’]=”値2-1″、$data[2行目][‘項目名2’]=”値2-2″…
…というように格納したい場合があります。

これを効率よく行う方法をメモしておきます。

問題点としては、PHPが動作する環境は、多くの場合UTF-8で、CSVはWindowsで編集した場合にはShift-JISになっていて文字コード周りの問題が発生する子っとが挙げられます。

下記関数では文字コードがバラバラだった時の対策として改行を統一しています。また、各値の前後に空白文字があった場合削除されるようにしています。

/**
 * Shift-JISで保存されたCSVファイルをUTF-8環境で読み込んで配列に格納する。
 * @param  string $filename CSVファイル。1列目が項目名、2行目以降がデータ。
 * @return array            $dat[行][項目名]="値"の配列。
 */
function getSJISCSV($filename)
{
    // ファイルを読み込んでUTF-8に変換して改行を統一した後に行ごとに分けて、行ごとにstr_getcsv関数で分割
    $dat = array_map('str_getcsv', explode("\n", preg_replace("/\r\n|\r|\n/", "\n", mb_convert_encoding(file_get_contents($filename), "UTF-8", "sjis-win"))));
    // 行ごとの単なる配列を[項目名]=[値]の配列に変換、そのさい値の前後の空白文字や改行を削除
    array_walk($dat, function (&$a) use ($dat) {
        $a = array_combine($dat[0], array_map('trim', $a));
    });
    // 1行目の項目名の列を削除
    array_shift($dat);
    return $dat;
}

これで一気に多次元配列に変換できます。

カテゴリーPHP

質問・コメントなどあると嬉しいです