EC-CUBE2 出力したCSVの商品合計数が画面と一致しない

2016.12.08

EC-CUBE2のCSVダウンロードでデータが出力されず半日ほど悩まされたので解決方法の備忘録です。

問題が発覚したきっかけ

EC-CUBE2の管理画面「商品管理>商品マスター」でCSVダウンロードを実行したときのこと、商品マスター画面に表示される商品の件数とCSVに出力される商品の件数が一致しないことで問題が発覚しました。
画面上の商品件数は約1000件、それに対してCSVの商品件数は約700件。なぜか300件くらい差が有ります。

そっと見なかった事にして画面を閉じたら翌週バレました。ついでに隠したこともバレてしこたま怒られました。人間悪い事するとバレますから隠さず報告しましょうね。以上の経緯があって、渋々調査した結果が今回になります。

環境

サーバー情報

EC-CUBEバージョン 2.13.5
PHPバージョン 5.6.27
DBバージョン MySQL 5.1.73

状況

  • 画面:管理画面の「商品管理>商品マスター」
  • 実行した処理:「CSVダウンロード」
  • 現象1:画面の商品件数とCSVの商品件数が一致しない
  • 現象2:なんどCSVダウンロードを行っても件数は変動しない
  • 現象3:商品を10件程度に絞ってCSVダウンロードすると全件出力される場合もある

以上の状況から、何らかの条件に一致するデータが出力されていないと予想しました。そこから解決の糸口を見つけようと思ったのですが、カテゴリや登録時期、入力されている文字数の量など、ありがちな共通点はなにも見つかりません。

散々ネットを彷徨い、ようやく原因に一致する情報を見つけました。

原因

まず、出力されなかった原因ですが、特殊文字でした。

解決のヒントになったのは以下の質問と回答です。

商品詳細ページを覗いてみると、本当に有りました特殊文字。表示されない全データにも特殊文字が入っていることを確認。これで原因は特定しました。
※特殊文字の例:㈱や㌖など

でも、なんでデータの中に特殊文字が含まれるとCSVに出力されないんでしょう?

EC-CUBEで扱われる文字エンコードはUTF-8、それに対しCSVの文字エンコードはSJIS。つまりDBから取得したデータをCSVへ出力するタイミングで変換が実行されていると言うことになります。この時に特殊文字が含まれているとUTF-8からSJISへの変換がうまく出来ずデータが抜け落ちてしまうようです。

CSVもUTF-8で出力すれば良いのに、なんでわざわざSJISに変更するんだろう。…と思ったのですが、たぶんUTF-8だとエクセルで開けないからですね。CSVを見るだけならエクセルの方が分かりやすいですしね。

対応方法

原因が分かったので対応方法を考えます。

  • 特殊文字を無くす
  • UTF-8のまま出力する
  • 頑張って上手いこと変換する

見ていてなんとなく分かるかもしれませんが、上から順番に私が楽な対応方法です。試しに上の2案を提案してみましたた。もちろん却下です。

仕方が無いので上手い事する方法を模索します。

UTF-8をSJISに変換するときに特殊文字が変換できず抜け落ちる。なら、いっそ特殊文字を無視しましょう。と言うわけで、以下のサイトを参考に対応しました。

以下のコードをガスっと追加。

// data/class_extends/helper_extends/SC_Helper_CSV_Ex.php
public static function &fopen_for_output_csv($filename = 'php://output')
{
$fp = fopen($filename, 'w');
stream_filter_append($fp, 'convert.iconv.utf-8/cp932//TRANSLIT'); // 追加
stream_filter_append($fp, 'convert.eccube_lf2crlf');
return $fp;
}

ポイントは

//TRANSLIT

。これを追加したことによって特殊文字を無視してUTF-8をSJISに変換してくれます。以上で無事に出力されました。

問題解決まで半日近くかかりました。しょっちゅう文字コードに悩まされてる気がします。

関連する記事