【PHP】CSVファイルを読み込んで配列に変換する方法。(BOMを削除する方法も)

PHPでCSVファイルを読み込み、配列にする方法

①formのenctypeを”multipart/form-data”にして、POSTで送信します。

<form method="post" action="" enctype="multipart/form-data">
<input type="file" name="load_file" accept=".csv"><br>
<input type="submit" value="読み込み">
</form>

②適当な変数にPOST通信で送られてきたファイルを入れます。

$file = $_FILES['load_file'];

③ファイル操作クラス「SplFileObject」を用いてオブジェクトを作成。この際、引数にはファイルのパスを記述する。その後は繰り返し文などで行ごとに連想配列を作成する。

$csvObj = new SplFileObject($file['tmp_name']);
        $csvObj->setFlags(SplFileObject::READ_CSV); 

foreach ($csvObj as $line) {
        $csvRowArray[] = $line;
}

④以下のような配列が出来上がります。

array(3) {
  [0] => array(5) {
    [0] => string(3)
    "あ" [1] => string(3)
    "い" [2] => string(3)
    "う" [3] => string(3)
    "え" [4] => string(3)
    "お"
  }[1] => array(5) {
    [0] => string(3)
    "か" [1] => string(3)
    "き" [2] => string(3)
    "く" [3] => string(3)
    "け" [4] => string(3)
    "こ"
  }[2] => array(1) {
    [0] => NULL
  }
}

EXCELで作ったCSVを読み込むとデータサイズがおかしい?

エクセルで作った言語コードがUTF-8のCSVファイルを先程の方法で読み込むと、以下のような配列が出来上がりました。

array(3) {
  [0]=>
  array(5) {
    [0]=>
    string(6) "あ"
    [1]=>
    string(3) "い"
    [2]=>
    string(3) "う"
    [3]=>
    string(3) "え"
    [4]=>
    string(3) "お"
  }
  [1]=>
  array(5) {
    [0]=>
    string(3) "か"
    [1]=>
    string(3) "き"
    [2]=>
    string(3) "く"
    [3]=>
    string(3) "け"
    [4]=>
    string(3) "こ"
  }
  [2]=>
  array(1) {
    [0]=>
    NULL
  }
}

1つ目の要素「あ」のデータサイズが他と比べて大きくなっていることがわかります。見た感じ、「あ」の文字以外入っていないように見えますが・・文字単体と比較しても一致しません。

if($csvRowArray[0][0] == "あ"){
  //false
}

これは、BOM(Byte Oder Mark)といい、符号化されたテキストの先頭に付けられる3バイトのデータなのだそう。エクセルなどのアプリケーションはBOMが無いと文字コードが判別できないので、「このテキストの文字コードはUTF-8ですよ」と知らせてあげる役割を持っているようです。

メモ帳などのアプリケーションからBOM無しの形式に変換することもできるのですが、それだとエクセルで開いたときに文字化けします。

そこで、以下のコードを追加して読み込んだCSVファイルからBOMを消去してあげましょう。UTF-8の場合は、「0xEF 0xBB 0xBF」を削除すればOKです。

$csvRowArray[0][0] = preg_replace('/^\xEF\xBB\xBF/','',$csvRowArray[0][0]);

これで、BOM付きのCSVファイルからBOMを削除した状態で読み込めるようになります。

コメント

タイトルとURLをコピーしました