Help us understand the problem. What is going on with this article?

【PHP】配列の順番が変わった時でも、あまりコードを変更しないで値を取得する方法を考えてみた

CSVファイルを読み込んだ時って、各項目を配列にして処理したりしますよね。
で、$email = $csvData[5]; みたいにインデックス指定で値を取得したりして。

そして、ある時に突然の仕様変更。

末尾に項目が追加になれば何の問題もないんですが、途中に項目が追加されたら大変です。

今まで$csvData[5];で取れてたemailが、$csvData[6];になり、それ以降の項目もインデックス値が全部ズレてきてしまう。
項目数が5、6個だったらまだマシだけど、これが50個あったりすると修正ミスも起きやすいでしょう。

そこで、インデックス指定をしないで、配列から値を取得する方法を考えてみました。

環境

  • php7.3
  • laravel5.8

流れ

  • CSVファイルの読み込みクラスを作成
  • コンストラクタでインデックス変数を定義
  • あとは変数を使って配列から値を取得する

具体例

public class MyCsv{
    public function __construct()
    {
        $this->setIndex();
    }

    private function setIndex(){
       collect([
           'ID',
           'NAME',
           'EMAIL',
           'TEL',
           'ADDRESS',
       ])->each(function($v, $i){
           //メンバー変数(配列のインデックス定数)を動的に生成。順番が大切
           $this->$v = $i;
       });
    }

    /**
     * CSVの1レコードを取得してなんかやる
     * 
     * @param array $csvRecord 1レコードのデータ配列
     */
    public function logic(array $csvRecord){
        $id = $csvRecord[$this->ID];
        $name = $csvRecord[$this->NAME];
        $email = $csvRecord[$this->EMAIL];
        $tel = $csvRecord[$this->TEL];
        $address = $csvRecord[$this->ADDRESS];
    }

こんな感じで作っておく。

・・・そして、ある日、仕様変更がはいる。

「名前」の後ろに「ふりがな」を追加して、「電話番号」の後ろに「携帯番号」を追加するよー。

こんな時でもsetIndex()の該当場所に項目を追加するだけで、値を取得しているコードの変更はなし。

public class MyCsv{
    public function __construct()
    {
        $this->setIndex();
    }

    private function setIndex(){
       collect([
           'ID',
           'NAME',
           'KANA', //追加
           'EMAIL',
           'TEL',
           'TEL_MOBILE', //追加
           'ADDRESS',
       ])->each(function($v, $i){
           //メンバー変数(配列のインデックス定数)を動的に生成。順番が大切
           $this->$v = $i;
       });
    }

    /**
     * CSVの1レコードを取得してなんかやる
     * 
     * @param array $csvRecord 1レコードのデータ配列
     */
    public function logic(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];
    }
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away