ウェブメールに送ったメールのタイトルが文字化けします?? - PHPプロ!Q&A掲示板

1390

  • 0P

ウェブメールに送ったメールのタイトルが文字化けします??

質問日時 / 2008年8月16日 00:28 (最終編集:8月16日 11:37)    回答数 / 12件

Questioner:  horowasan  このエントリーをはてなブックマークに追加 

キーワード / メール    文字化け    タイトル   

こんにちは,よろしくお願いします。
yahooメールなどのウェブメールにメールを送ると,タイトル(件名)のところが文字化けします。(Outlook等で受信したものは文字化けしません。本文は,どちらで受信しても文字化けしません。)
対応の方法を教えてください。
次のような,コードを使っています。文字セットはutf-8を使っています。よろしくお願いします。

  1. mb_language("ja");
  2. $title = mb_convert_encoding("タイトル", "JIS", "utf-8");
  3. $address = mb_convert_encoding(aaa@bb.cc,"JIS","utf-8");
  4. $message = "本文";
  5. $honbun = mb_convert_encoding($message,"JIS","utf-8");
  6. $from = "From: xxx@yy.zz";
  7. $xmail = "X-Mailer: PHP5";
  8. if (@mb_send_mail($address,$title,$honbun,$from . "\r\n" . $xmail)){
  9.   echo $row_rsUs['US_mail']."にメールを送信しました。";
  10. } else {
  11.   echo "送信に失敗しました。";
  12. }

この質問への意見の募集は締め切られ、ポイントは既に配分されました。
意見を投稿することはできますが、ポイントを受け取ることはできません。



ツリー一覧

┗A01tezcello手元の環境(PHP 5.2.6, SquirrelMail 1.4.8)では文
 ┗A01-1horowasantezcelloさん,ありがとうございます。 >mb_langu
  ┗A01-1-1tezcello> >mb_send_mail はヘッダや本文はチャンと変換して
   ┗A01-1-1-1horowasantezcelloさん,ありがとうございました。 >>CODE mb
    ┗A01-1-1-1-1tezcello現象を正確に掴みたいので、 mb_encode_mimeheader()
     ┗A01-1-1-1-1-1horowasantezcelloさん,いつもご丁寧にお答えいただき,ありが
      ┗A01-1-1-1-1-1-1tezcello確認したい事は、YAHOOメールに届いたメールのソース
       ┗A01-1-1-1-1-1-1-1horowasantezcelloさん,ありがとうございます。 私の送った
        ┗A01-1-1-1-1-1-1-1-1tezcello> 別のwebメールでは,tezcelloさんの例示の通り(略)
         ┗A01-1-1-1-1-1-1-1-1-1horowasantezcelloさん,ありがとうございます。 > タイト
          ┗A01-1-1-1-1-1-1-1-1-1-1tezcello楽天メールのヤツは、送られて来たメールのヘッダ部を
           ┗A01-1-1-1-1-1-1-1-1-1-1-1horowasantezcelloさん,返信が遅くなってすみませんでした。

回答一覧

並び替え:

A01 満足
answerertezcello [8月18日 13:11]

手元の環境(PHP 5.2.6, SquirrelMail 1.4.8)では文字化けはありませんでした。

mb_language は指定していますが、mb_internal_encoding は未指定ですよね?デフォルトで何か(例えば EUC)が指定されていたりしませんか?
mb_send_mail はヘッダや本文はチャンと変換してくれる事になっていますが、バージョンによってはミスをしている事があったような記憶があるのですが...(というか以前に失敗して自力で変換したような気が...)
与えられた文字列が mb_internal_encoding であると想定しているでしょうから、間違った変換をしてしまっていたり、MIME が正しく変換されていなかったりしませんか?

正しく変換すると
Subject: =?ISO-2022-JP?B?GyRCJT8lJCVIJWsbKEI=?=
となると思います。実際に届いているメールのヘッダはどうなっているでしょうか?
もし、メールヘッダが上記のようでなければ、変換に失敗しているでしょうし
上記の通りであれば、お使いのWebメーラは、日本語にうまく対応できていないのかもしれません。

IEはMIMEを無視して勝手に変換してくれるので、本来文字化けするのが正しい状態でも文字化けしなかったりするようです。ですから、IEで文字化けしない->正しくメールを送信できた では無いと思います。

この意見に回答する

ツリーへ TOPへ

A01-1
replyerhorowasan [8月18日 23:16]

tezcelloさん,ありがとうございます。

mb_language は指定していますが、mb_internal_encoding は未指定ですよね?デフォルトで何か(例えば EUC)が指定されていたりしませんか?
私は,次のように設定しています。これで,よろしいでしょうか?
  1. mbstring.language = Japanese
  2. mbstring.internal_encoding = UTF-8

mb_send_mail はヘッダや本文はチャンと変換してくれる事になっていますが、
しかし,ヘッダが文字化けするのですよ。本文はきれいに送れるのですが…。なぜなのでしょうか?

>以前に失敗して自力で変換したような気が
私,も以前にやったときは,ヘッダのタイトル部分のみを,mb_encode_mimeheaderで変換をしてうまくいった様な気がするのですが…。
mb_encode_mimeheadermb_convert_encodingも引数は同じで良かったでしょうか?
つまりmb_encode_mimeheader("タイトル", "JIS", "utf-8");で良いのでしょうか? 
この場合,utf-8の”タイトル”という文字列をJISに変換するという内容を意味するのだったでしょうか?

もし再度,ご覧でしたらお答えいただけるとありがたいです。よろしくお願いします。

この意見に回答する

ツリーへ TOPへ

A01-1-1 満足
replyertezcello [8月19日 00:27]

> >mb_send_mail はヘッダや本文はチャンと変換してくれる事になっていますが、
> しかし,ヘッダが文字化けするのですよ。本文はきれいに送れるのですが…。なぜなのでしょうか?
どのように文字化けするのかを確認する為にも、メールヘッダのSubject: の行がどのようになっているかを教えて頂けませんか?

> つまりmb_encode_mimeheader("タイトル", "JIS", "utf-8");で良いのでしょうか? 
mb_encode_mimeheader ( 'タイトル', 'JIS', 'B', "\r\n" , 9 );
という感じだと思います。(省略できる引数もありますが)
マニュアルをご覧ください。
http://jp2.php.net/manual/ja/function.mb-encode-mimeheader.php

この意見に回答する

ツリーへ TOPへ

A01-1-1-1
replyerhorowasan [8月19日 18:55]

tezcelloさん,ありがとうございました。
  1. mb_encode_mimeheader ( 'タイトル', 'JIS', 'B', "\r\n" , 9 );
と入力したら,文字化けが直りました。
しかし,問題が発生しました。文字が全角で12文字のところで切れてしまい,それ以降の文字が表示されませんでした(yahooメールで確認しました。)。まったく,難しいものなのですね。いったい何がどうなっているのでしょうか?不思議です。

このような現象については,お心当たりはありますでしょうか?また,上記の引数の最後の5番目の引数は何を表しているのでしょうか?もしよろしければ教えていただきたいです。
できましたら,お教えくださいますようお願い申し上げます。

この意見に回答する

ツリーへ TOPへ

A01-1-1-1-1 満足
replyertezcello [8月20日 00:28]

現象を正確に掴みたいので、
mb_encode_mimeheader() を使わない場合(=文字化けしている状態)
mb_encode_mimeheader() を使った場合(=途中で切れている状態)
のそれぞれのメールヘッダの Subject: のところ(後者は、これを含む3行程)を見せてください。

件名を公開したくなければ、テスト用の件名で試してください。

長い件名が切られるのは Subject ヘッダの継続行に、空行が入る場合がほとんどです。ですが、
  日本語12文字で改行が入るのは短すぎる...
  エンコードが UTF-8 のままかも...
  改行文字は "¥n" だけだったか...
などと疑問点があり、スッキリしません。最初の回答にも書いた通り当方の環境では再現しないので、OSやPHPのバージョンに因る差異があるかも知れません。
文字化けしているヘッダの状態を見るのが解決の近道ですので、どうぞお願いします。
  確認したいのは、以下です。
  ・正しくISO-2022-JPに変換されているか
  ・正しくMIME変換されているか
  ・Subject: の次の行はどうなっているか



mb_encode_mimeheader() の第5引数は、長い件名を変換する場合にヘッダの1行が長くなり過ぎない様にする為に指定しています。
これを指定しないと、毎行74文字(程度)で改行されるのですが、指定をすると1行目のみ指定文字分だけ短い時点で改行します。(MIME の関係で必ず74文字という訳ではないですが)
メールヘッダのキーワードとして、先頭に "Subject: " の9文字が入るので、第5引数に 9 を指定しています。

この意見に回答する

ツリーへ TOPへ

A01-1-1-1-1-1
replyerhorowasan [8月22日 23:29]

tezcelloさん,いつもご丁寧にお答えいただき,ありがとうございます。
(遅くなって申し訳ありませんでした。)
コードについては,次のようにしています。タイトルは,日本語で30文字くらいのものです。

  1. mb_language("ja"); 
  2. $title = mb_encode_mimeheader("タイトル", 'JIS', 'B', "\r\n" , 9 );
  3. $address = mb_convert_encoding(aaa@bb.cc,"JIS","utf-8"); 
  4. $message = "本文"; 
  5. $honbun = mb_convert_encoding($message,"JIS","utf-8"); 
  6. $from = "From: xxx@yy.zz"; 
  7. $xmail = "X-Mailer: PHP5"; 
  8. if (@mb_send_mail($address,$title,$honbun,$from . "\r\n" . $xmail)){ 
  9.   echo "メールを送信しました。"; 
  10. } else { 
  11.   echo "送信に失敗しました。"; 
  12. }

PHPのバージョンは5.2.6です。

>  確認したいのは、以下です。
>1 ・正しくISO-2022-JPに変換されているか
>2 ・正しくMIME変換されているか
>3 ・Subject: の次の行はどうなっているか

なるほど,多分,この中のどれかが変なのですね。これらを確かめるには,どのようにすればよいのでしょうか?
  1. echo mb_detect_encoding($title);
とすると,ISO-2022-JPと表示されるのでしょうか?

また,正しくMIME変換されているかどうかを見るには,どうしたらよいのでしょうか?
Subject: の次の行は,yahooメールでは,From:となっていますが,正常に表示されています。前にもお話いたしましたように,Subject:以外は,いたって正常に表示されています。(Subject:も短くなってはいますが,今は,文字化けもありません。)

もし,よろしければ教えてください。よろしくお願い申し上げます。

この意見に回答する

ツリーへ TOPへ

A01-1-1-1-1-1-1 満足
replyertezcello [8月23日 00:38]

確認したい事は、YAHOOメールに届いたメールのソースを表示しないとわかりません。
YAHOOメールにこの機能があるのか不明ですが、無ければ自分宛に送る等して、普段(PCで)お使いのメーラで確認してもいいでしょう。
Outlook Express なら、こんな手順でしょうか?(情報が古いので、違っていたらゴメンナサイ)
http://www.atmarkit.co.jp/fwin2k/win2ktips/360oemsgp/oemsgp.html
実際にどんなヘッダで送られたかを確認したい訳です。

タイトルが日本語で30文字もあれば、タイトルの部分はこんな感じになっているはずです。
MIMEでエンコードされているので、日本語として読むことは出来ません。
http://www.atmarkit.co.jp/fnetwork/rensai/netpro03/netpro01.html
(これ以降にもいろいろ何かが続いているはずです)

Subject: =?iso-2022-jp?B?GyRCIVobKEIgGyRCNmIbKEIgGyRCTUsbKEIg?=
 =?iso-2022-jp?B?GyRCRnwbKEIgGyRCOWYbKEIgGyRCIVs6RxsoQiA=?=
 =?iso-2022-jp?B?GyRCQmcbKEIgOCA1IBskQiFzGyhCIE8gRiBG?=
 =?iso-2022-jp?B?IBskQiF1GyhCIBskQkF3GyhCIBskQk5BGyhC?=
 =?iso-2022-jp?B?IBskQkw1GyhCIBskQk5BIVozWiF8GyhC?=
 =?iso-2022-jp?B?GyRCRTchWxsoQigyMDA4LzA4LzIyKQ==?=

これは楽天市場からのメールで、デコードすると
【 金 曜 日 号 】最 大 8 5 % O F F & 送 料 無 料【楽●天】(2008/08/22)
となります。

Subject: ... の次の行が、1つ以上の半角ブランクかタブで始まっていなければいけないのです。
これが、空行(先頭が改行文字)だとそれ以降が本文だと解釈されてしまい、タイトルが短くなってしまったりします。
また、メールのタイトルという性格上、タイトルの文字列に改行は含む事が出来ませんが、大丈夫ですよね?

この意見に回答する

ツリーへ TOPへ

A01-1-1-1-1-1-1-1
replyerhorowasan [8月24日 21:24]

tezcelloさん,ありがとうございます。

私の送ったメールのタイトルの最初の部分も
=?iso-2022-jp?B?
ではじまっていました。つまり,iso-2022-jp にきちんと変換されていたということなのですね(たぶん?)そして,74文字目で途切れていました。yahooメールは,このような設定になっているみたいです。

別のwebメールでは,tezcelloさんの例示の通り,=?iso-2022-jp?B?・・・という表示になっていて,最後まで表示されていました。タイトルが長すぎるってことなのですよね。きっと・・・。

> Subject: ... の次の行が、1つ以上の半角ブランクかタブで始まっていなければいけないのです。
> これが、空行(先頭が改行文字)だとそれ以降が本文だと解釈されてしまい、タイトルが短くなってしま> たりします。
> また、メールのタイトルという性格上、タイトルの文字列に改行は含む事が出来ませんが、大丈夫ですよ  ね? 

つまり,タイトルと本文が,ひとつのテキスト文書みたいなものなのですね。
私は,タイトルと本文は別々に送信されるものと思っておりました。目からうろこです。
改行は挿入していません。

長すぎるタイトルを改善するのが一番の解決策のようですね。
長い間,ありがとうございました。大変勉強になりました。

この意見に回答する

ツリーへ TOPへ

A01-1-1-1-1-1-1-1-1 満足
replyertezcello [8月24日 22:52]

> 別のwebメールでは,tezcelloさんの例示の通り(略)
だとすると、YAHOO では Subject: の継続行を許さない仕様なんでしょうねぇ。
手を抜き過ぎな感じもしますが...

> つまり,タイトルと本文が,ひとつのテキスト文書みたいなものなのですね。
「ソースをみる(表示する)」で見る事ができるものが、メールの正体です。
一固まりのテキストの前半にメールヘッダと呼ばれるもの、後半にメールの本文(や添付ファイル等)。
前半後半を区切るのは、最初に出てくる空行(最初の空行以降を後半部分と見なす)って事のようです。


> 長すぎるタイトルを改善するのが一番の解決策のようですね。
タイトルに半角文字を含むと、エンコード後の文字列長が意外と長くなる場合があります。
  例えば
  123いろはabcあかさ(1)
  のように半角全角の切り替えが何度もあると、かなり長くなるはずです。
一応、ご参考まで。

この意見に回答する

ツリーへ TOPへ

A01-1-1-1-1-1-1-1-1-1
replyerhorowasan [8月25日 22:31]

tezcelloさん,ありがとうございます。

> タイトルに半角文字を含むと、エンコード後の文字列長が意外と長くなる場合があります。

半角は含まれていませんでした。
ちなみに,以前に,楽天メールのタイトルのデコードの例をお示しいただきましたが,このデコードのやり方を教えていただけませんでしょうか? ツールとなるページみたいなものがあるのでしょうか?やはりmb_decode_mimeheader で行うのでしょうか?できれば,よろしくお願いします。

手詰まりです。今は,PEAR::MAILを使ってみようと思っています。うまくいくといいのですが・・・。

この意見に回答する

ツリーへ TOPへ

A01-1-1-1-1-1-1-1-1-1-1 満足
replyertezcello [8月25日 23:42]

楽天メールのヤツは、送られて来たメールのヘッダ部をそのまま掲示しただけです。
僕が作成した訳ではありません。

mb_decode_mimeheader() を使うのはメールを受信する様なものを作る時ですので、今回は mb_encode_mimeheader() でしょう。

もしもYAHOOメールが複数行に跨がるヘッダを最初の1行しか理解しない(Subject:ダケかも知れませんが)なら、PEAR を使おうがダメでしょうね。
PHPから送るのでは無く、普通のメーラ(OE, Thunderbird, etc.)でYAHOOメール宛に送った場合でも部分的にしかタイトルとして表示できないのかをご確認ください。

この意見に回答する

ツリーへ TOPへ

A01-1-1-1-1-1-1-1-1-1-1-1
replyerhorowasan [8月31日 00:47]

tezcelloさん,返信が遅くなってすみませんでした。
PEAR::MAILを試すのに手間取ってしまいまして・・・。

試してみたところできました。問題なく長いタイトルが表示されました。
いろいろお騒がせしました。お付き合いいただきありがとうございました。
また,よろしくお願いします。

この意見に回答する

ツリーへ TOPへ

<<質問一覧へ



Pick Up Q&A

Q
マジッククォートとmysql_real_escape_string
 このエントリーをはてなブックマークに追加 
A
magic_quotes_gpcでは、SQLインジェクション対処は十分できません。主な理由として、以下が上げられます。 ・magic_quotes_gpcは文字コードを考慮しないで処理するので、Shift_JISを使っている場合、SQLインジェ...

>>続きを読む

SQLインジェクション対策は時と場合で使う関数が変わります。その時にあったものを使いましょう。

▲解説者:岡本(アシアル株式会社 教育コーディネーター兼 システムエンジニア)