MENU
DATE:2019/04/29

【PHP】SplFileObjectを使ってCSVファイルを展開すると変な位置で区切られる現象について

このエントリーをはてなブックマークに追加

PHPではCSVファイルを扱うのにいくつかの方法が用意されています。
どの方法を使うかは、処理速度や個人的な使いやすさで選べばよいと思います。

処理速度の考察については様々な方が結果をオープンにしていますので、
参考にしてみるといいかもしれません。

【PHP】その CSV 変換、本当に「fgetcsv」でいいの? (フェンリル | デベロッパーズブログ)
php CSVを読み込むときの速度・メモリーについて : プログラマー社長の「日々発見」

僕は処理速度やデータの扱いやすさの点から
もっぱらSplFileObjectクラスを使用してCSVファイルの操作を行っています。

データを配列として扱いやすいSplFileObjectクラスは、
僕のお気に入りなのですが先日思わぬところで躓くことがあったのでその原因と解決方法について書いていきたいと思います。

トラブル:「CSVデータが変なところで区切られる」

今まで、fopen関数、fgetcsv関数を用いてファイル読み込みを行っていたシステムを
処理速度改善のためにSplFileObjectクラスに変更したところ
意図しない位置に改行「\n」が入るという現象が起きました。

「”△△”,”□□”,”〇〇”」という状態が正解だとすると、
「”△△”,”□”
“□〇〇”」というようなイメージです。

すべての列で同じ現象が起きていれば処理機能の問題であるといえるのですが、
発生しているのはいくつかの列のみでした。

原因:「共通点は『能』という字で終わるパターン」

区切りがうまく機能しないデータの共通項を調査してみると、
すべてのデータの末尾に『能』という字が入っていました。

試しに『能』の字を削除してみると、
正常にデータを区切ることができました。

もう一つ試しに『能』の字の後に空白を入れてみても
問題なくCSVデータの読み込みに成功しました。

これで原因は末尾に『能』の字がある状態のとき、
意図しない改行「\n」が認識されてしまうということがわかりました。

ダメ文字によるイタズラ

どうやらこの現象、ダメ文字と呼ばれる文字群が引き起こす現象のようです。
正確には、CSVの文字コード(SJIS)からWebの文字コード(UTF-8)に変換するタイミングによって
CSVデータの読み込み結果が変わってしまうようです。

ダメ文字は『能』の他にいくつか常用漢字も存在しますので、
参考までにこちらのページをご確認ください。
Shift_JISのダメ文字 – fudist

対策:「文字コードの変換タイミングも大事」

今回の問題が発生したときの処理の流れとして、
「① CSV読み込み」=> 「② データを列ごとに配列化」=>「③ 配列ごとに文字コード変換」=>「④ データ処理」
というような流れで一連の処理を行っていました。

そうすると、②の段階でダメ文字の位置で改行されてしまい、
そのまま文字コードをUTF-8に変換すると意図しない形にデータが変換されてしまいます。

なのでこういうような形で処理の流れを変えるといいようです。
「① CSV読み込み」=>「② CSVデータの文字コード変換」=>「③ データを列ごとに配列化」=>「④ データ処理」

こちらの記事を参考にさせて頂きました。
SplFileObjectでのCSVファイル読み込みでの文字化け対策

対策②:「CSVデータ自体を加工しちゃえばいいやん」

こちらはちょっと力技となってしまいますが、
CSVデータ生成の段階で問題のダメ文字が末尾に来ないようにしてしまう方法です。

末尾に半角スペースを入れたり、言葉自体を別の表現に変えてしまうということでも
問題の解決を図ることができます。

ただ、こちらの方法ですと根本的な問題解決にはなりませんので、
問題解決の重要度や作業コストなどを考慮して最善の方法を選んでいただければと思います。

まとめ:「文字コードはやっかい」

というわけで今回は、SplFileObjectクラスを使った時にダメ文字のトラブルについて
その原因と解決方法をまとめました。

Web、CSVファイル、Excelファイル、その他様々な媒体と
文字コードの違いってすごいややこしいです。

普段あまり気にすることが少ないので、
そこが原因でトラブルが起きた場合、原因究明に手間取ってしまいますね。

全部UTF-8に統一されればいいのにと思いました。

この記事を書いた人

わたなべ

HTML5とCSS3とPHPとJavascriptとMySQLで開発をします。 フレームワークはLaravelを勉強中です。 地方の観光地として有名な洞窟に隣接するカフェが好きです。

この人の記事を見る
ブログ記事一覧へ戻る