goo blog サービス終了のお知らせ 

おばらっち亭(マカナイ付き)

こちらが、本家には載せられない当店自慢の裏メニューでございます

PHP:CSVでダウンロードしてExcelでみると文字化け

2005-05-17 01:08:00 | PHPとかMySQLとか

2005-05-17 追記:
MySQL4.1.12 では Added cp932 Japanese character set. が行われたらしい。


以下は、2004-10-10 22:58:10 投稿の記事

とある土建屋さんに納入した、とあるシステムの一部の機能に、
「MySQL + UTF-8なテーブルの中身を、SJISなCSVでダウンロードする」
というのがありました。
※ 環境はWAMP: Win2k,Apache2.0系,MySQL4.1.1系(UTF-8),PHP5.0(内部UTF-8)

こんな単純な機能ですので、バグが入り込む要素自体が無いのですが、
ダウンロードしたCSVをExcelに食わせると、
"~"などの一部の文字が文字化けしていることが発覚。

「UNICODEをSJISに変換する為のコードマップは複数存在し、選択を間違うと文字化けする」
という知識は獲得済みだったため、
MySQLとPHPの文字コードの指定の仕方をGoogle先生に尋ねるだけだと思っていたら、
意外と根深いことが判りましたので、ここに備忘録として書いておきます。

修正前のソースでは、
1. MySQLからデータを引っ張る前に、"SET NAMES SJIS"を実行し、サーバサイドで文字コード変換を実施している。
2. PHPでは、SJISなデータをそのままCSVとしてファイルに落としている。
という実装が行われていました。

# Excelには 文字コードの指定 といった概念がないため、Excelでは何も出来ず。

MySQL4.1.1系つまり、現段階のMySQLでは、
UTF-8をSJISに変換する際にコードマップを指定できない(実装が固定的な)ため、
MySQLにUTF-8⇒SJISの変換をやらせると、Windows環境で文字化けしてしまうと判明。

ならばと、
MySQLからデータを引っ張る際は、UTF-8のままで、
PHP側で、mb_convert_encoding($str, 'SJIS-win', 'UTF-8') を実行することで解決しました。

テストコードは、こんな感じで、


<?php>
$fwt = '~'; // FULLWIDTH TILDE
$sjis = mb_convert_encoding($fwt, 'SJIS-win', 'UTF-8');
$utf8 = mb_convert_encoding($sjis, 'UTF-8', 'SJIS-win');
?>
<html><body>
~ eq <?php echo $utf8 ?>
</body></html>


SJIS-winSJISと指定すると、PHP上でも文字化けが発生することを確認できます。
Windowsで飯を食ってる方々は、こういった現象であっさり行き詰まってしまうんではないかと。

2004/10/10 追記
解決方法は、
JIS X 0221 附属書3表3 - 3.1.1の(1)に書いてあったりします。
Windowsの実装が間違っているのだが、困ったことに広く流布してしまったので、
いまさら「間違ってました」といって修正できる問題ではない。

# もしくは、MSには間違いを訂正する気がないのかもしれない

最新の画像もっと見る