いわゆる機種依存文字をPHPでメールする
よく判らん。
先日仕事で作ったケータイサイトで、クレームがついた。
別にクレームでもないか。
要するにいわゆる「機種依存文字」が化けるんだけど?って。
ケータイサイトなんで、HTML側はShift-JISで、PHPはUTF-8です。
SJISのサイトからSJISで受け取った文字列をUTF-8に変換して、各種処理(入力チェックとか、内容の確認)をして、HTMLで表示する直前にSJISに戻すことをしている。
で、メールを送信する際に
mb_language('ja');
を実行しているので、ISO-2022-JPで扱われることになる。
e-mail メッセージのエンコーディングとして使用します。有効な言語は、"Japanese", "ja","English","en", "uni" (UTF-8) です。 mb_send_mail() は、e-mail をエンコードする際にこの設定を使用します。
言語とその設定は、Japanese の場合は ISO-2022-JP/Base64、uni の場合は UTF-8/Base64、English の場合は ISO-8859-1/quoted printable です。
PHP: mb_language - Manual
はぁ…
フツーにメーラーを使ってメール送ると「ISO-2022-JP」じゃん!って思ってたのもあって、このあたりのテストを怠ってたわ。ケータイサイトだし、自由入力って住所氏名くらいのもんだから、そんな機種依存文字の問題が出るとは想定してなかったなぁ。*1
でもよく考えればマンション名にローマ数字を使ってるところもあるな(そういうマンションに住んでたのを忘れてた)。そうすると文字化けするな。
いや、そもそもSJIS→UTF-8の変換では問題がないのに、mb_send_mail()に限らずmbstring系の処理でUTF-8からISO-2022-JPやSJISに変換すると機種依存文字が化けるっつーのはどういうこった!?
一応入力内容ってのはデータベースに入れてるからいいんだけど、と思ったら管理画面いらないってゆーから、作ってないわ(一応僕のローカルのテスト環境にはあるけど)。
色々考えた結果、まずはメールのエンコードをUTF-8にする方法を考えた。
でもそれにはmb_send_mail()を捨てる必要がある。
件名($subject)は自前で変換する必要があるので、mb_encode_mimeheader()をはさむ。本文($body)はUTF-8なので、対応する必要はない。
少なくともPC宛てには問題がなかった。
mb_language('uni'); mb_internal_encoding('UTF-8'); (中略) $mail_header .= "Content-Type: text/plain; charset=utf-8\r\n"; $mail_header .= "Content-Transfer-Encoding: 7bit"; (中略) mail($mail, mb_encode_mimeheader($subject), $body, $mail_header);
しかし、ケータイってUTF-8メールって受け取れるの?
ググッってみたけど確証はなし。
そしてたどり着いたのが、「ISO-2022-JP-MS」という文字コード。
今度は本文($body)も変換する必要が出てくるので、mb_convert_encoding()を実行することになる。
でもって、以下のようにしてみた。*2
mb_language('ja'); mb_internal_encoding('UTF-8'); $e_subject = mb_encode_mimeheader($subject); $e_body = mb_convert_encoding($body, 'ISO-2022-JP-MS'); (中略) $mail_header .= "Content-Type: text/plain; charset=ISO-2022-JP\r\n"; $mail_header .= "Content-Transfer-Encoding: 7bit"; (中略) mail($order_email, $e_subject, $e_body, $mail_header);
ここで「e_」とつけるのはエンコード済みですよって印。完全な個人的趣味。だってどこで変換したのか忘れるんだもん。
Becky!も、Hotmail経由のWindows Live Mailも機種依存文字を正しく表示してくれた。
一応自分のアドエスのW-ZERO3メールも正常に受け取ってくれた。
他のケータイは大丈夫だろうか?(WILLCOMユーザで悪かったね)*3
そして、ヘッダにもISO-2022-JP-MSと指定しなくてもいいのか?
誰か教えてください。
(追記)
SJIS-winというのもあるんだね。