こんにちは、主にtenpuの開発を行っている @gorou です。 tenpuで複数ファイルアップロードを行った場合、ダウンロードはzipで圧縮して提供しています。この時によく発生するのが文字化けです。 tenpuで実施した文字化け対策について紹介します。
文字化けが起こる原因
2種類の問題が同時に発生します。
1.ファイル名の文字コード
WindowsはCP932
(内部的にはUTF-16)*1、Mac OS XやLinuxなどはUTF-8
が利用されています。そのため、Windows→Mac、Mac→Windowsでファイルを受け渡しすると、文字コードが異なるため文字化けしてしまいます。
2.zip展開時の文字エンコード
zipを展開する際、OSによって強制的に固定の文字エンコードが行われてしまい、文字化けするケースがあります。
1. Windows7 より前
文字コードがCP932
のため、zip展開時は強制的にCP932のエンコードが行われます。 CP932
以外の文字コードの場合、文字化けする可能性があります。よくMacのzipをWindowsで開くと文字化けする原因は、この強制的にCP932でエンコードを行ってしまうWindows OS側の問題でした(受け手側からするとMacが悪いと思われていますが...)
2. Windows7
内部の文字コードはUnicodeに変わりましたが、表示はCP932という状態になりました。ただし、zip展開時の強制CP932エンコードは行われてしまうため、文字化けする可能性があります。ただ、任意適用のパッチがMicrosoftから提供されており、パッチを適用すると文字コードを判別してエンコードを行ってくれるようになるため、文字化けせずzip展開が行えるようになります。*2
3. Windows7 より後
Windows7同様、内部の文字コードはUnicodeに変わりましたが、表示はCP932という状態です。zip展開時に文字コードを判別してエンコードを行ってくれます。そのため、文字コードの変換は必要なくなりました。
4. Mac OS X
zip展開時にUTF-8エンコードが行われるため、基本的には問題ありません。UTF-8-macとUTF-8で正規化形式が異なるという問題はありますが、今回は省略します。
5. Linux
Linuxが利用しているunzipコマンドは日本語に対応していないため、Linux上でunzipする際、文字化けるので注意が必要です。
実施した対策
カンペキな対応は難しいのですが、UserAgentからOSを判定し、OSにあったファイル名の文字エンコードを実施したzipファイルを提供することで対策しました。
事前処理
ファイル名に対して、UTF-8
→ CP932
に変換できない文字の置換と、ファイル名に利用できない文字・記号などの除外を行います。詳細は省きます。
zip圧縮
3種類のzipを作成しました。Mac向けzip、Windows7向けzip、その他Windows向けzip
Mac向けzip
MacおよびWindowsどちらのファイル名でも対応できるよう、以下の優先順位でファイル名をエンコードします。
<?php $filename = mb_convert_encoding($filename, 'UTF-8', 'ASCII,JIS,UTF-8,eucJP-win,SJIS-win');
Windows7向けzip
CP932
で強制的にエンコードされるため、CP932
に変換しておきます。
※提供されているパッチは、任意適用のパッチのため適用者はとても少ないと判断しました。以下のコードは、パッチ適用者には文字化けしてしまいます。
<?php $filename = mb_convert_encoding($filename, 'SJIS-win', 'ASCII,JIS,UTF-8,eucJP-win,SJIS-win');
その他Windows向けzip
事前処理で変換できない文字の置換をおこなっているので、OS側の文字コード自動判別で問題なく変換ができます。そのためファイル名のエンコード変換は行いません。(tenpuでは、Windows7以前のWindows OSは対象外としています)
ダウンロード
ダウンロードページに訪れた人のUserAgentを見て、OSを判別して上の3種類のzipの中から最適なzipを提供することで文字化けを回避しています。
まとめ
ファイル名およびzip展開時の文字化け対策についてまとめました。
文字化けの再現と対策を色々なパターンで試していた時、A
を実施するとX
はOK
だけどY
はNG
、B
を実施するとX
はNG
でY
はOK
みたいな状況が発生してとても混乱しました。まだまだ一部の文字で文字化けが発生することもあると思うので、見つけられた方ご連絡をお待ちしております。
文字化けで困っている方に参考になればと思います。