LoginSignup
4
3

More than 5 years have passed since last update.

【PHP】CSV読込備忘録

Last updated at Posted at 2018-12-21
sample.csv
123456789,0,234567890,ABCDE
345678901,1,456789012,BCDEF

上記のようなCSVファイルを読み込んで、数字はint型に変換し、配列に詰めて、さらにごにょごにょするというのをやってました。
しかし、下記のように、1行目の先頭が0になってしまうという問題とご対面。
その時の備忘録です。

array(4) {
  [0]=>
  int(0)
  [1]=>
  int(0)
  [2]=>
  int(234567890)
  [3]=>
  string(5) "ABCDE"
}
array(4) {
  [0]=>
  int(345678901)
  [1]=>
  int(1)
  [2]=>
  int(456789012)
  [3]=>
  string(5) "BCDEF"
}

疑惑① fgetcsv

Google先生で調べていくと、fgetcsvで苦しんだ先人の記事がたくさん出てきました。
やれsetlocaleだの、やれ文字コード変換だの、試してみたものの、結果は変わらず。

こりゃfgetcsvそのものを諦めるかと、SplFileObjectを使って書き直してみました。
ところが、結果は変わりません。

そこで、CSVファイルを読み込み、配列に詰めた段階でvar_dumpしてみました。
※詰め方が違うのは見逃してください。

array(2) {
  [0]=>
  array(4) {
    [0]=>
    string(12) "123456789"
    [1]=>
    string(1) "0"
    [2]=>
    string(9) "234567890"
    [3]=>
    string(5) "ABCDE"
  }
  [1]=>
  array(4) {
    [0]=>
    string(9) "345678901"
    [1]=>
    string(1) "1"
    [2]=>
    string(9) "456789012"
    [3]=>
    string(5) "BCDEF"
  }
}

…12?9じゃなくて?

疑惑② CSVファイル

どうやら先頭に意識していない3バイトが含まれているようです。

「php csv 先頭」でググって答えにたどり着きました。BOMです。
UTF-8とは:BOM付きとBOMなし(UTF-8N)の違い――Unicode関連の文字エンコード

先頭に数バイトつくって厄介すぎませんかね。

ダウンロードしてきたCSVファイルを流用して編集したのですが、確かに秀丸で開いてみたらBOMにチェックが入ってました。

というわけで、このBOM対策を行います。
※【参考】[解決済] ExcelでUTF-8のCSVを吐いたらwith BOMだったせいでPHPでの取込に不具合が出た件

BOM対策① CSVファイルをBOMなしに変更

エディタなどでCSVファイルをBOMなしに変更してしまいます。いちばん簡単です。

BOM対策② BOMを置換

そうはいってもBOMがあろうがなかろうが対応したいよね…という場合はこちら。

$count = 0;
$handle = fopen($file_dir.'sample.csv', 'r');
while (($data = fgetcsv($handle)) !== FALSE) {
    if ($count === 0) {
        $data[0] = preg_replace('/^\xEF\xBB\xBF/', '', data[0]);
    }
    $row[] = $data;
    $count++;
} 

※この記事は、アウトプットネタ棚卸し Advent Calendar 2018 22日目の記事も兼ねています。

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3