ホームページ制作 オフィスオバタ

[PHP]Shift-JISの&#文字列をUTF-8文字に逆変換する

 Shift-JISで、PHP+MYSQLのサイトを構築すると「特殊文字の壁」があります。

どういうことかというと、UTF-8のほうが表現できる文字数(特殊漢字など)が多く、Shift-JISでは表現できない文字(特殊文字)があるという点です。

これがShift-JIS文字化けの要因の一つです。

ただ近年「SJIS-win」「CP932」などを使用すると、Shift-JISでも特殊文字が使用できるようになりました。

これによりHTMLでShift-JISを使う分にはさほど困ることは起こらなくなりました。

ただ、Shift-JISでは特殊文字は「&#文字」で表現されます。
例えば「塡」という漢字は「塡」に変換されて保存されます。

見た目は数字ですが、ブラウザを通すと「塡」という文字で表示されます。
そのためHTMLで使用する分には、&#文字のままでOKなのです。

ただしこのままだと、CSV出力など、テキストファイルに出力する時に、&#文字のまま出力されてしまいます。

出力したCSVファイルに&#文字がそのまま入っていたら、それこそ文字化け扱いです。

今回、これを何とかすべく、Shift-JISのまま&#文字を本来の文字へ逆変換する方法について調べてみました。

&#文字の一般的な逆変換方法

&#文字を通常の文字に戻すためには、「html_entity_decode()」関数を使用します。

&#文字を通常文字に変換してくれます。
使い方は以下の通りです。

$outcode = html_entity_decode("塡");

これだけで「塡」という文字に変換してくれます。
簡単簡単。
とこの時は思いましたが、落とし穴がありました。

html_entity_decode関数を使用しても変換されないケースがありました。

html_entity_decode()関数を使用すれば、&#文字が本来の文字に変換されるのですが、変換されず&#文字のまま出力されているケースがありました。

なぜ?

と思い調べてみたところ、次のことがわかりました。

「&#」が「&#」で保存されていました。

「&」もHTML上では特殊文字の一つです。
文字化けさせないように特殊文字「&」として保存します。
そのため、「塡」は「塡」と保存されていました。

「&#22625」をhtml_entity_decode()関数で変換すると、「塡」になります。

&→&に変換するだけで、肝心の&#文字は変換してくれません。
なぜならば、&と#の間に「amp;」という文字があるため、特殊文字として認識されないからです。

こういった場合はどうすれば本来の文字に戻せるのでしょうか?

&#文字を本来の文字に戻す方法

「&」が特殊文字で変換されている場合は、次のような方法で対処することができます。

$outcode = html_entity_decode(html_entity_decode("塡"));

html_entity_decode()関数を2回コールします。
1回目のコールで「塡」が「塡」に変換されます。
2回目のコールで「塡」が「塡」に変換されます。

コロンブスの卵的な発想ですが、&を先に「&」に変換してから、本来の文字に変換する方法です。

無論&が変換されていない「塡」を二重にコールしても特に文字化け等は起こりません。

私はこの方法で&#文字を全て本来の文字に逆変換してCSV出力することができました。

今回は思ったより悩みました。

今回は、html_entity_decode()関数で元の文字に戻らない場合があり、その原因がわからずとても悩みました。

文字コードテーブルを作成し強引に変換してみたりなど、いろいろ試行錯誤しましたが、完全に変換されずどこかしら「抜け」がありました。

そんななか、たまたまコーディングミスでhtml_entity_decode()を2回記述してしまいました。ところが変換が上手くでき、要因を調べたところ先述の&が変換の邪魔をしていたことがわかりました。

偶然とはいえ、重要なhtml_entity_decode()関数の癖を知ることができました。

html_entity_decode()関数で意図する変換がされない場合、2回コールするとうまくいくケースがあるかもしれません。

モバイルバージョンを終了