PHPのプログラムで、Cookieの文字列がSJISで指定されていて、受け側が全部UTF-8で死ぬという事件がありいろいろ調べつつ対応(笑)
この辺、いつも調べながら「なんだっけ?」って思い出しているので、チェックのポイントだけメモっておきます。
UTF-8にしかない文字
扱える文字の種類はUnicodeであるUTF-8の方が圧倒的に多いので、UTF-8では入力、表示できても、SJISに対応する文字が無いことがあります。このあたりの文字でいったい何が起きるか、というのは文字を扱うシステムではチェックする必要がありますね。
たとえば
- ほっけ(魚へんに花)
- よう(目+華)
- つかむ(てへんに國)
- おう(森鴎外のおう、難しい方)
などです。これらについてはSJISに変換した時点で文字化けしますが、「文字化け後、何バイトになるか?」にも留意する必要があります。たとえばデータベースに格納する場合、文字化けしても登録できればエラーにはなりませんが、桁数オーバーしてしまうとエラーです。
特に、Unicodeのサロゲートペア文字(2文字分のコードで1文字を表現するタイプの文字)は、文字化け後も2文字とかになることがあるので注意が必要です。
SJISの拡張文字
SJISもいろんな拡張やこれまでの歴史的経緯で関係各社が追加した文字があるようです。詳しくは正直把握しきれていないのですが、少なくとも業務システムでありがりな「人名」などに関すると思われる文字が「IBM拡張文字」というカテゴリに含まれています。このあたりの文字を入力したり、参照したりした場合にどうなるか、という点もチェックする必要がありますね。
髙 閒 塚 德 﨑 彅 弴 燁 珉 鄧
PHP:mb_convert_encodingの取り扱い
第3引数の「変換元文字コード」を「auto」に指定した場合に、うまく変換できない(エラーになる)ケースがありました。たしか「㈱」(括弧付きの株)などだったかと。これを回避するには、明示的に変換元を指定する必要があるようです(他に良い手があるかもしれませんが、ちょっと調べきれませんでした)。
この時、変換元の文字種が複数あり得る場合は、mb_detect_encodingで文字コードの判定をしてから処理を分けるとよいでしょう。ただ、この場合も文字コード名が取れない文字があったので要注意です。たしか「㈱」や「髙」でした。おそらくですが、自動判定の場合には「SJIS-Win」は選択されないのかもしれません。この㈱や髙はSJIS-winに含まれる文字なので、判定不能になってしまったのかもしれません(括弧付きの株はJIS X 0213:2004に登録されているIBM拡張文字)。

図解入門よくわかる最新ファイル形式と文字コードの基本と仕組み (How‐nual Visual Guide Book)
- 作者: 若林宏
- 出版社/メーカー: 秀和システム
- 発売日: 2003/01/10
- メディア: 単行本
- 購入: 1人 クリック: 34回
- この商品を含むブログ (1件) を見る
参考ページ
- 文字コードの考え方から理解するUnicodeとUTF-8の違い/ギークを目指して
- http://equj65.net/tech/charcode/
- UTF-8 → cp932(Shift_JIS)変換表/fudist
- https://sites.google.com/site/fudist/Home/vim-nihongo-ban/mojibake/utf8-cp932conv
- 新常用漢字表が迫るUnicode移行、「シフトJIS」では対応不可能/日経コンピュータ
- http://itpro.nikkeibp.co.jp/article/COLUMN/20091209/341831/
- Microsoftコードページ932
- Microsoftコードページ932 - Wikipedia
- php/mb_detect_encoding(文字コード検出)
- http://php.net/manual/ja/function.mb-detect-encoding.php
- php/mb_convert_encoding(文字コード変換)
- http://jp2.php.net/manual/ja/function.mb-convert-encoding.php