こんにちわ。花粉の季節が近づいてきてビクビクしている高橋です。
ちょっとタイトルが長くなってしまいましたが今回はメールの文字化けについて書きたいと思います。
最近では日本語のメールをUTF8で送るサービスも多くなってきたと思いますが、
まだまだJISで送る方が主流だと思います。
JISで送っているのでJISで扱っていない文字は当然文字化けします。
しかし、世の現場にはこんな会話が繰り広げられていることでしょう。
「このメールの”①”ってところが文字化けってんだけど」
「日本語のメールはJISって文字コードで送ってましてー
それJISで扱ってない文字なんで文字化けちゃうのしょうがないですねー」
「GmailとかAmazonのメールではそういう文字送れてるけど?」
「(ほんとだ、ゔぅ)なんででしょうね、ハハハ…」
日本語のメールはJISで送るというのがスタンダードで、本来はJISで扱っていない文字が
化けてしまうのは「仕様です」で済ませられたはずが文字化けせずに送れている
サービスが存在しちゃってます。
これは困りましたね。
文字化けしないで送るカラクリ
メールのヘッダにはこのメールはどの文字コードで作成してますよという情報を入れます。
JISの場合はこんな感じです
1 |
Content-Type: text/plain; charset=ISO-2022-JP |
GmailでもAmazonでもこのようになっていますがなぜ文字化けしないのでしょう?
ずばり、ヘッダでJISと指定しているが、内容は別な文字コードで送っているからです。
別とは言ってもUTF8など全くな別ものではなく、JISを拡張した文字コードを使用します。
ISO-2022-JP-MSという文字コードがあり、半角カナやJISにはない記号を扱うことができます。
PHPだと
PHPで日本語メールを送る簡単な方法といえばmb_send_mail()ですね。
この関数は言語に適切な文字コードにエンコードしてくれて
ヘッダに文字コードの指定なども自動でセットしてくれる便利なやつです。
ソースはこんな感じ
1 2 3 4 |
<?php mb_language('ja'); mb_internal_encoding("UTF-8"); mb_send_mail('dummy@aainc.co.jp', 'テスト', 'テストです'); |
当たり前ですが、こんなことをしようものなら
1 |
mb_send_mail('dummy@aainc.co.jp', 'テスト', '①②③'); |
この通り、化けてしまいます。
ではどうすればいいかというと mail() を使い、ヘッダの指定やエンコードは
自分で処理します。
ソースはこんな感じになります。
1 2 3 4 5 6 7 8 |
<?php mb_internal_encoding("UTF-8"); mail( 'dummy@aainc.co.jp', mb_encode_mimeheader('テスト', 'ISO-2022-JP-MS'), //エンコードはISO-2022-JP-MSで行う! mb_convert_encoding('①②③', 'ISO-2022-JP-MS'), //エンコードはISO-2022-JP-MSで行う! "Content-Type: text/html; charset=\"ISO-2022-JP\";\n" //ヘッダはISO-2022-JPを指定する! ); |
これならこの通り、文字化けせず!
ただ、ISO-2022-JP-MSという文字コードがPHPでサポートされるように
なったのは5.2.1からでそれ以前のバージョンでは使えませんのでご注意ください。
http://php.net/manual/ja/mbstring.supported-encodings.php
以上になりますが、来たる2/27にアライドアーキテクツのエンジニア・クリエイター勉強会を
開催いたします。
参加無料なのでぜひぜひご参加ください!
http://connpass.com/event/1812/
最近ではコードを書く機会がめっきり減って来てプログラマー35歳限界説に恐怖しています。 このブログを口実に無理矢理新しい技術に触れていきたいと思っています。