CSVファイルを読み込んだ時って、各項目を配列にして処理したりしますよね。
で、$email = $csvData[5];
みたいにインデックス指定で値を取得したりして。
そして、ある時に突然の仕様変更。
末尾に項目が追加になれば何の問題もないんですが、途中に項目が追加されたら大変です。
今まで$csvData[5];
で取れてたemailが、$csvData[6];
になり、それ以降の項目もインデックス値が全部ズレてきてしまう。
項目数が5、6個だったらまだマシだけど、これが50個あったりすると修正ミスも起きやすいでしょう。
そこで、インデックス指定をしないで、配列から値を取得する方法を考えてみました。
環境
- php7.3
- laravel5.8
流れ
- CSVファイルの読み込みクラスを作成
- コンストラクタでインデックス変数を定義
- あとは変数を使って配列から値を取得する
具体例
publicclassMyCsv{publicfunction__construct(){$this->setIndex();}privatefunctionsetIndex(){collect(['ID','NAME','EMAIL','TEL','ADDRESS',])->each(function($v,$i){//メンバー変数(配列のインデックス定数)を動的に生成。順番が大切$this->$v=$i;});}/**
* CSVの1レコードを取得してなんかやる
*
* @param array $csvRecord 1レコードのデータ配列
*/publicfunctionlogic(array$csvRecord){$id=$csvRecord[$this->ID];$name=$csvRecord[$this->NAME];$email=$csvRecord[$this->EMAIL];$tel=$csvRecord[$this->TEL];$address=$csvRecord[$this->ADDRESS];}
こんな感じで作っておく。
・・・そして、ある日、仕様変更がはいる。
「名前」の後ろに「ふりがな」を追加して、「電話番号」の後ろに「携帯番号」を追加するよー。
こんな時でもsetIndex()
の該当場所に項目を追加するだけで、値を取得しているコードの変更はなし。
publicclassMyCsv{publicfunction__construct(){$this->setIndex();}privatefunctionsetIndex(){collect(['ID','NAME','KANA',//追加'EMAIL','TEL','TEL_MOBILE',//追加'ADDRESS',])->each(function($v,$i){//メンバー変数(配列のインデックス定数)を動的に生成。順番が大切$this->$v=$i;});}/**
* CSVの1レコードを取得してなんかやる
*
* @param array $csvRecord 1レコードのデータ配列
*/publicfunctionlogic(array$csvRecord){$id=$csvRecord[$this->ID];$name=$csvRecord[$this->NAME];$email=$csvRecord[$this->EMAIL];$tel=$csvRecord[$this->TEL];$address=$csvRecord[$this->ADDRESS];//追加で取得する項目$kana=$csvRecord[$this->KANA];$telMobile=$csvRecord[$this->TEL_MOBILE];}