実際はLaravelでのお話。
本当はLaravel Excelを使いたかったのだけど、
Excelならうまくいく日本語処理が、CSVだとどうもうまくいかなかったので諦めて他のライブラリ探し。
PHPでCSVを扱うにはライブラリはいくつもあるし、厳密でなければ一から書くことも難しくはないが、今回はLeague/CSVを使うことに決定。
最新の安定版は、
PHP >= 7.0.10
composerでインストール。
composer require league/csv
公式サイトの情報が充実しているので、そこを読めばだいたいわかるはずですが、
CSVは英語前提なので、日本語を含むCSV、それもExcelで出力したようなSJIS-winのCSVだと単純に読み込もうとしてもうまくいきません。
<?php
use League\Csv\Reader;
$reader = Reader::createFromPath('/path/to/file.csv', 'r');
$reader->setHeaderOffset(0);
$header = $reader->getHeader();
$records = $reader->getRecords();
foreach ($records as $record) {
//
}
公式サイトの最初に出てくる上記のコードだと、日本語(SJIS-win)は文字化けしてしまう。
そこで入力のエンコーディングを変更します。
https://csv.thephpleague.com/9.0/converter/charset/
http://memo.eightban.com/php/league-csv
<?php
use League\Csv\Reader;
use League\Csv\CharsetConverter;
$reader = Reader::createFromPath('/path/to/file.csv', 'r');
$encoder = (new CharsetConverter())->inputEncoding('SJIS-win');
$records = $encoder->convert($reader);
foreach ($records as $record) {
//
}
これでSJIS-winのCSVを文字化けせずに読み込めます。
本当はCSV1行目の列名をキーにした連想配列で欲しいけど、そこは各自でなんとかしましょう