前のページ

PHPでCSVを使った実装をしている時にBOMのせいで思わぬ時間を取った話

みなさんこんにちは、あべ いさぢです。

PHPでCSVを使ったツールを作らないといけなかったのですが思わぬ所で時間を取ってしまったのでアウトプットとしてこの記事を残します。


CSVを使うと1列目はBOMが入る

UTF-8 BOM付きCSVを使っていたとします。

CSVの中身は下記とします。

demo,PHP,100

この時、見た目はこのままなのですが実際のCSVの中身は下記になっていて「EF BB BF」が付いています。

EF BB BFdemo,PHP,100

CSVの1列目はBOMが入って3バイトが付くのは仕様みたいです。


詰まった時のコード

下記みたいなコードを書いていました。

var_dump(CSVの1列目のデータ === 'demo');

CSVの1列目のデータは「demo」なのに何度試してもなぜか「false」になりました。

そこでデバッグをしました。

<?php
$file = fopen('sample.csv', 'r');
$data = fgetcsv($file);

var_dump($data);

fclose($file);

var_dumpの結果は下記になります。

array(3) {
  [0]=>
  string(7) "demo"
  [1]=>
  string(3) "PHP"
  [2]=>
  string(3) "100"
}

「demo」は4文字なのに「string(7)」の表示になるのは変ではないですか?

「3」多いですがこれはBOMのせいです。


BOMを除く

正規表現を使えば実現できます。

<?php
$file = fopen('sample.csv', 'r');
$data = fgetcsv($file);
$firstColumn = $data[0];

$firstColumn = preg_replace('/^\xEF\xBB\xBF/', '', $firstColumn);

var_dump($firstColumn);

fclose($file);

これで下記の表示にCSVの「demo」の文字数が4になります。

array(3) {
  [0]=>
  string(4) "demo"
  [1]=>
  string(3) "PHP"
  [2]=>
  string(3) "100"
}


戻る