laravel5.8¦CSVファイルのヘッダーを毎回判定してインポートする

1 min read読了の目安(約1400字

概要

CSVのインポートでヘッダーの位置が都度都度変わる可能性があるので(そんなことあるのか)、ヘッダーを毎回判定してDBへインポートしてほしいとのことなので実装してみました。

環境

・laravel 5.8
・php 7.2

Goodby CSVを使用していますが、Goodby CSV自体の設定については調べるとたくさんでてくるので割愛します

ヘッダーも読み込むようにする

$config = new LexerConfig();
$config->setDelimiter(',')
       ->setToCharset('UTF-8')
       ->setFromCharset('sjis-win');

->setIgnoreHeaderLine(true) は、ヘッダーを飛ばして読み込んでしまうので消しました。

ヘッダーとインサートしたいデータにわける

$interpreter->addObserver$rowsにヘッダーもインサートしたいデータも多次元配列で入っている状態です。
$headerListsには定数ファイルなどで作成したヘッダーの配列をいれておきます。
今回はヘッダーにエラーがある場合、一律で「ヘッダー情報が存在しません」のメッセージを表示させます。

エラーメッセージにエラーがあったヘッダー名を表示させたい場合

ヘッダーが足りない場合はエラーを表示するようにしていますが、array_diffは重複していない値がとれるので、ふくめてほしいヘッダー名をエラーメッセージに追加することもできます👌

// ヘッダーとインサートしたいデータにわける
$headers = array_slice($rows, 0, 1, true); 
$header = Arr::flatten($headers);

// header数のチェック
if(!empty(array_diff($headerLists, $header))){
    return $error = ['error_messages' => 'ヘッダー情報が存在しません'];
}

// unsetでヘッダー分の配列をつめてインサートしたいデータのみにする
unset($rows[0]);
foreach($rows as $row) {
    $convertRows[] = array_combine($header, $row);
}

ヘッダーのみで空データの場合、unsetとarray_combineの間に、データが存在しているか判定してもよいと思います。(今回は割愛)
これ以降のコードは調べるとたくさんでてくるのですが、foreachとswitch文を使用しました!

< 動作のまとめ >
① array_sliceで特定の配列だけとりだす
② array_sliceでとりだした分の配列をunsetでつめる
③ array_combineでインサートしたいデータの配列のkeyをヘッダー名にする

🍬🍬🍬

あまり使うことはないかもしれないですね…
実装してほしいといわれたときはう〜〜〜む、と思ったのですが形になってよかったです( '֊' )