mail()で送信したメールのタイトルが正しく表示されない問題

このQ&Aのポイント
  • mail()で送信したメールのタイトル(Subject)が適切に表示されません。'コンタクトフォーム'として表示させる予定でしたが、予期しない文字列が表示されています。
  • メールヘッダー情報を確認すると、予期しない文字列が自動的に付加されていることが分かりました。これが原因と考えられます。
  • この問題を回避する方法をご教示いただきたいです。また、メールヘッダーについても簡単に説明していただけると助かります。
回答を見る
  • ベストアンサー

mail()で送信したメールのタイトル(Subject)がきちんと表示

mail()で送信したメールのタイトル(Subject)がきちんと表示されません。’コンタクトフォーム’とタイトルに表示させようとしたところ,次のように表示されます。 =?ISO-2022-JP?B?GyRCJTMlcyU/JS8lSCVVJSkhPCVgGyhC?= これで良いはずと思っていたのですが,念のため,ヘッダー情報を参照してみると, =?ISO-2022-JP?Q?=3d=3fISO-2022-JP=3fB=3fGyRCJTMlcyU/JS8lSCVVJSkhPCVgGyhC?= =?ISO-2022-JP?Q?=3f=3d?= となっておりました。原因は,mail()関数が,「=?ISO-2022-JP?Q?=3d=3f   =?ISO-2022-JP?Q?=3f=3d?=」を自動的に付加していることにありそうだということまでは想像がついたのですが,これの回避方法が分かりません。 メールヘッダーの簡単な解説を含めて,この場合の回避方法を教えていただきたいです。よろしくお願いします。

  • PHP
  • 回答数7
  • ありがとう数7

質問者が選んだベストアンサー

  • ベストアンサー
回答No.7

■メールに関して 私は、 >mb_encode_mimeheaderが多重でかかっているような気がします。 と書きました。 そして、質問者さんは、書籍を参考に少なくとも一回は、自分でmb_encode_mimeheaderを実行し、変換をかけていますよね。 ということは、「自分でエンコードをかけている上に、ライブラリ側でもエンコードをかけているっぽい」と仮定できます。 そして、今回参考にされた書籍は、CIのバージョンが1.6.1の時点での書籍です。 であれば、もしかしたらクラスの構造が変わったのかもとか、そういうところまで考える必要があります。 なんせ今1.7.2まで出てますので。 そうしたところで、CI_Emailクラスを見てみますと、subjectメソッド内で、「_prep_q_encoding」というものがあるのが分かります。 でこのメソッドを見てみると、斜めに読んでもおそらく、"Q"のほうでエンコードをかけているのが分かります。 なので、この_prep_q_encodingを動作しないようにCI_Emailクラスを書き換えるか、libraryディレクトリにMY_Emailクラスを作って、_prep_q_encodingが文字列を何もしないでそのまま返すようにメソッドをオーバーライドしてやる必要があるのが分かるかと思います。 ■セッションに関して それは単純にブラウザが残したHTMLのキャッシュが表示されてしまっているだけじゃないですか。 HTMLのキャッシュを残さない方法に関しては色々検索してみてください。header関数で指定したりするものになります。 まぁ、とりあえず、困ったらフレームワークの中身見て、どういう挙動してるかぐらいは何となく見てみたほうだよいです。 CodeIgniterは、どのフレームワークよりも内容が平たく出来ているので、挙動を追うのはそんなに難しくないと思いますし。(CakePHPで内容を追うのはとても大変でした) がんばってください。

emikouji
質問者

お礼

hogehoge78さん,ありがとうございます。 Email.phpをのぞいてみました。なるほど,_prep_q_encodingというプライベートメソッドを定義して,これを使ってSubjectをエンコードしていたのですね。そこで強制的にQuoted Printable形式を指定する’Q’が挿入されていたみたいですね。 MYクラスを作って,この中でプライベートメソッド_prep_b_encodingを定義し,base64でサブジェクトをエンコードするようにして,これ以外にエンコードしないという方法でやってみようと思います。 また,セッションについてですが,HTMLのキャッシュを残さない方法を講じる必要があるとのことですが,勉強していろいろと試してみたいと思います。先が見えたような気がします。 私も,数々(40冊は超えると思います。)のPHP関係やHTML関係の本を持っていますが,キャッシュについては見落としていました。(というか,この部分を強調している本はあまりなかったように思います。)以前に同様の質問を,様々なサイトにアップしましたが,これほど適切なお答えはありませんでした。 hogehoge78さん,本当にありがとうございました。 それから,「CodeIgniter徹底入門」とても良い本だと思います。必要な人があれば,強く勧めていきたいと思います。 これからも,このような本がたくさん出版されるといいなと思っています。 また,何かありましたらよろしくお願いします。

その他の回答 (6)

回答No.6

該当する書籍は、たまたま手元に持っていたのですが、 mb_encode_mimeheader関数の3番目の引数は、「B」か「Q」を選択するためのものですので、書籍のように「UTF-8」を3番目に渡すのは明らかに間違っています。 で、それとは別に、質問者さんのような現象が発生している理由に関してなんですが、 mb_encode_mimeheaderが多重でかかっているような気がします。 <?php $str = "コンタクトフォーム"; $encoded = mb_encode_mimeheader($str, 'ISO-2022-JP'); echo mb_encode_mimeheader($encoded, 'ISO-2022-JP', 'Q'); ?> としてみると、似たような文字列になる。 とりあえず、使用しているCodeIgniterのCI_Emailクラス中に自動的に変換処理をかけているメソッドがないか、また、MY_Emailクラスとか作って継承クラス作っているのを忘れていないかとか、チェックしてみてください。

emikouji
質問者

補足

hogehoge78さん,御検証ありがとうございます。 hogehoge78さんのコードにヒントを得て, $subject = mb_encode_mimeheader($subject, 'iso-2022-jp','B'); としてやってみましたが,やはり結果は同じでした。 Subject: =?iso-2022-jp?Q?=3d=3fISO-2022-JP=3fB=3fGyRCJTMlcyU/JS8lSCVVJSkhPCVgGyhC?= =?iso-2022-jp?Q?=3f=3d?= つまり,CodeIgnaiterのemailライブラリに問題があるということなのではないでしょうか?2重にエンコードされるという問題があるのだと思います。(実際には,emailライブラリを使わずにPEAR::Mail等を使って回避することで対応しています。) 私は,CodeIgniterに未来と希望を感じているものです。出来れば,もっとメジャーになってほしいと心から願っています。広く使われるようになってほしいと願っています。しかし,勉強するにつれて,どうしても,私1人では超えることの出来ない壁を感じています。 セッションライブラリに関する問題についても同様の思いをもっています。セッションはwebアプリでは必須ですから,事は重大です。別の話題で恐縮ですが,真剣にこの問題に向き合いたいと思っている私に免じてお付き合いいただきたいと思います。 同書の172ページのセッションのサンプルプログラムを実行し,カウンタが増えたところで(例えば5で),/destroyを実行しました。次に,session_sampleを実行すれば,カウンタは「1」に戻らなければならないはずです。しかし,また,同じ数5が表示され,再度,ブラウザの更新ボタンを押して,session_sampleを実行すると1に戻ります。たまに,きちんとdestroyされる事もあります。非常に不安定な印象のセッションです。 このような状態ですので,ユーザ認証機能などを実装しようとしたときに,ログアウト(「ログアウトしました。」とのメッセージが表示されます。)しても,ログアウトされず,再度ページを開くとユーザがログインした状態で1度表示されます。その後,ブラウザのボタンで最新の情報に更新するとログアウトされた状態となります。なぜこのような状況となるのか,私には分かりません。(これも,ごくまれに1度でうまく行くときもあります。) 有効期限等の問題なのでしょうが,私にはいっこうに理解できません。このままではCodeIgniterを使ったサイト構築を断念せざるを得ません。この辺りの事についても,ご指導いただけませんでしょうか? hogehoge78さん,どうかよろしくお願い申し上げます。

回答No.5

mb_convert_mimeheaderは正しい挙動をしています。 mimeヘッダはある程度長い文字がある場合は、自動的に文字を分割して、且つ、CR+LFで改行します。 また、mb_convert_mimeheaderは、内部文字コードを第二引数で指定した文字コードに変換をしてコンバートを行いますので、 <?php mb_internal_encoding("質問者さんがPHPファイルに記述している文字コード"); $subject = mb_convert_mimeheader("タイトル", "ISO-2022-JP"); ?> などとする必要があります。

emikouji
質問者

補足

hogehoge78さんありがとうございます。 おっしゃる通りやってみました。 mb_internal_encoding('UTF-8'); $subject = mb_encode_mimeheader($subject, 'iso-2022-jp'); しかし,ヘッダー情報は, Subject: =?iso-2022-jp?Q?=3d=3fISO-2022-JP=3fB=3fGyRCJTMlcyU/JS8lSCVVJSkhPCVgPmU8?= =?iso-2022-jp?Q?aiQvOVQkQyQ/ISkbKEI=3d=3f=3d?= となり,メーラーのタイトル表示は「=?ISO-2022-JP?B?GyRCJTMlcyU/JS8lSCVVJSkhPCVgPmU8aiQvOVQkQyQ/ISkbKEI=?=」となります。 このコードは,「CodeIgniter徹底入門」の第7章のコンタクトフォームの検証を行っている際に登場したコードです。 実は,CodeIgniterのemailライブラリから,mail()を利用しています。 そのためなのか何なのか,Quoted Printable形式だとして送信されてしまいます。 これは,CodeIgniterのemailライブラリが原因なのでしょうか?

  • kzkz-16
  • ベストアンサー率76% (10/13)
回答No.4

添付ファイルが無いなら mb_send_mail( がお勧めです。 mb_internal_encoding("UTF-8"); //ソースコードの文字コード mb_language("ja"); mb_send_mail(宛先,件名,本文,"From: "送信元""); 私の場合、これで件名の文字化けを解消できました。 ソースコードの文字コードをmb_internal_encodingで指定することで、件名や本文は自動で変換されます。

  • okmotokun
  • ベストアンサー率59% (92/155)
回答No.3

引数が間違っています。 mb_encode_mimeheader($subject); だけで良いと思いますが、ダメな場合は、第2引数に$subject文字列のエンコード文字セット名(sjis/euc-jp/utf8)を付けてみてください。 この関数は、与えられた文字列がJISでなければJISに変換してbase64エンコードするものですから、ISO-2022-JPを引数として与える必要は無いです。

  • okmotokun
  • ベストアンサー率59% (92/155)
回答No.2

subjectのISO-2022-JP変換には mb_encode_mimeheader()関数を使います。 詳細はマニュアルを見てください。

emikouji
質問者

補足

ありがとうございます。 実は,下記のように $subject = mb_encode_mimeheader($subject,'iso-2022-jp'); とすると, Subject: =?iso-2022-jp?Q?=3d=3fISO-2022-JP=3fB=3fGyRCJTMlcyU/JS8lSCVVJSkhPCVgGyhC?=  =?iso-2022-jp?Q?=3f=3d?= とヘッダー情報が送信されるので質問させていただいたのです…。 普通は,これでいいはずですよね。やはり,ヘッダー情報を入力した変数を作って,第4パラメータで指定してやる必要があるのでしょうか?まだやってみてませんが…?いかがでしょうか?

回答No.1

タイトルは、PHPの関数でbase64エンコードして、mail関数に渡してやると、いかがでしょうか。 $encode="UTF-8";// ←ソースのエンコード // タイトル $title="=?iso-2022-jp?B?".base64_encode(mb_convert_encoding("コンタクトフォーム","ISO-2022-JP",$encode))."?="; // 本文 $text=mb_convert_encoding("本文","ISO-2022-JP",$encode); // 宛先 $address="to@mail.com"; // 差出人 $from="From: from@mail.com"; // 送信 mail($address,$title,$text,$from);

emikouji
質問者

補足

ご回答ありがとうございます。 早速,次のようにしてやってみました。 $subject="=?iso-2022-jp?B?".base64_encode(mb_convert_encoding($subject,'iso-2022-jp','UTF-8')); しかし,この結果は, Subject: =?iso-2022-jp?Q?=3d=3fiso-2022-jp=3fB=3fGyRCJTMlcyU/JS8lSCVVJSkhPCVgGyhC?= 適正な表示は次のようなものです。 Subject: =?iso-2022-jp?B?GyRCJTMlcyU/JS8lSCVVJSkhPCVgGyhC?= 比較するとやはり,前半のところに, Quoted Printable形式であることを示すQの文字が入ったりなどしていて,適正に表示されませんでした。 この部分は,英語圏で開発されたPHPが標準で付加する仕様になっているのでしょうか?この部分を付加させないようにする,引数は無いのでしょうか? よろしければ,この後のご指導をよろしく願いします。

関連するQ&A

  • mailコマンドでは化けないSubjectがPOPで受信すると文字化け

    mailコマンドで、メールのタイトル一覧を表示した時には、Subjectは文字化けしていないのですが、 POP3でメーラ(WindowsのBecky)で受信すると Subjectが文字化けしてしまいます。 ヘッダ情報は以下のようになっています。 MIME-version: 1.0 Content-Type: text/plain; charset="iso-2022-jp" Content-Transfer-Encoding: 7bit 原因は何でしょうか?

  • メールのSUBJECT

    メールをMIMEエンコードし、別のプログラムで読み込んで、メールを送信していますが。。。 メールのタイトル文字が長すぎるため、下記のようにすると改行されてしまい、タイトルが半分消えてしまいます。 $str_title = mb_encode_mimeheader($title); そこで、下記のように変更しました。 $str_title = "=?iso-2022-jp?B?" . base64_encode(mb_convert_encoding( $title , "JIS" , "EUC-JP" )) . "?="."\n"; 別のプログラムでタイトルを表示させるとき、デコードされていない状態で表示されます。 ただし、メール受信のときのタイトルは表示されます。(メーラーはBeckyを使用しています。) どのようにしたら別のプログラムでも日本語が表示されるのでしょうか?

    • ベストアンサー
    • PHP
  • PHPからのHTMLメール送信

    PHP覚えはじめの初心者です。 下記のソースで自分宛にメールを送信すると、 会社のメールアドレスではHTMLメールとして受取れるのですが、 その他のメールアドレス(DION、ロリポップ、infoseek)、などでは 普通のテキストメールとしてソースが出てしまいます。 他にも何かヘッダーに付加したほうがいいのでしょうか? コツがありましたらご教授ください。 よろしくお願い致します。 <?php /* 送信先 */ $to = "hoge@hoge.com"; /* 題名 */ $subject = "HTML MAIL"; /* メッセージ */ $message = ' <html> <head> <title>テスト</title> </head> <body> <h1>テスト</h1> </body> </html> '; /* ヘッダー */ $headers = "MIME-Version: 1.0\r\n"; $headers .= "Content-type: text/html; charset=iso-2022-jp\r\n"; $headers .= "Content-Transfer-Encoding: 7bit\r\n"; $headers .= "From: hoge@hoge.com\r\n"; mail($to, $subject, $message, $headers); ?>

    • 締切済み
    • PHP
  • getMsg($msg_id)で、読み取ったメールソースから、本当のSubjectを復元したい、どうすればいいですか?

    メールのソースを見てみると、タイトルのほうが、こんなフォーマットで書かれております。 英語のタイトルは、Subject: Welcome to Flickr! - Read me 日本語のタイトルなら、 Subject: =?iso-2022-jp?B?GyRCJSIlcyUxITwlSCROJCo0aiQkGyhC?= 又は、 Subject: =?shift_jis?B?gZqQVpCii0mDR4OUg0CDk4NRg4qDSYOTksqQTYx2ieYgg1SDfYFbg0yDg4OTg3mBW4OTikqOboFJ?= そのメールのタイトルをPHPプログラミングで扱いたいんですけど、英語の場合は、何も問題なく、日本語を扱う場合は、どうやって、正常に戻せますか? 文字コード変換関数を使って $subject = mb_convert_encoding($subject, "EUC-JP","ISO-2022-JP"); $subject = mb_convert_encoding($subject, "EUC-JP","SJIS"); をいろいろ確かめましたけど、だめでした。 ご存じの方がいっらしゃいましたら、どうぞお教え下さい。 05-06-01 15:42 困り度1:暇なときに回答ください 回答件数:3件 この質問に対する回答は締め切られました

  • BCCに設定したアドレスが、ヘッダに表示されてしまう

    OutlookExpress6 の環境でアドレス帳のグループを作り、そのグループ名をBCCに設定してメールを送信したところ、メールアドレスがヘッダに表示されてしまう現象がおこりました。 以下のように、BCCに設定したアドレスの途中からヘッダに表示されてしまっています。 ※実際のアドレスは伏字にしています。 === ヘッダ上部省略 === To: =?iso-2022-jp?AAAAAAAA?= <mail@address_a> >, =?iso-2022-jp?XXXXXXX?= <mail_address_x>, =?iso-2022-jp?YYYYYYY?= <mail_address_y>, =?iso-2022-jp?ZZZZZZZ?= <mail_address_z> Subject: ?iso-2022-jp?ABCDEFG?= === 以下省略 === BCCには10件のアドレスを指定していますが、最後の3件分(その直前のアドレスの「>,」から)が表示されてしまいます。 アドレス帳のバグでしょうか? 解決策がありましたらご教授ください。

  • メール転送時にSubject変更

    全然分かってないのですが、例えば .forward などを編集する事で、メール転送時にSubjectに特定の文字を付加する事は可能でしょうか? というのも部署内で共通に使用するメールアドレスをメンバーに転送する予定なのですが、初心者ばかりなのでヘッダーの to で確認してもらうのが難しそうなんですね。何か簡単に対処できればと思ったのですが… 少し調べまして、Perlのスクリプトを仕込めば実現可能だというのは分かったのですが、もう少しお手軽にできる方法があればと思って質問しました。 回答お待ちしてます!

  • MIMEでエンコードされたMailのSubjectのデコード、エンコード

    mailにおいて、MIMEにてエンコードされたSubject: の内容をテキストに落とすと例えば下のような エンコードされた文字列になります。 これをデコードし、かつエンコードするための VisualC++のコードを教えてください。 Subject: =?ISO-2022-JP?B?GyRCJTUlcyVXJWslYSUkJWsbKEI=?= よろしくお願いします。

  • IMAP4でsubjectが検索ヒットしない

    メールサーバ(dovecot-1.0.7)にてIMAPでsubject検索すると 一致しているワードが含まれているにもかかわらずヒットしない場合があります。 SUBJECTはISO-2022-JPでエンコードされているようですが 件名が長いと分割されます。 しかし分割されている場合、個別にしか検索してくれないようです。 (なので単語がバラバラになったら検索にヒットしない) (例) Subject: =?iso-2022-jp?B?UmU6IBskQkNtMFUhJzojN24kTjtENmIkLBsoQjIwMTMxMTEx?= =?iso-2022-jp?B?MDAbJEIxXyRHJDkhIxsoQg==?= ↓ Re: 注意:今月の残金が20131111 00円です。 メールのSUBJECTを分割させない、もしくは分割も検索対象に含める場合はどうすれば よいでしょうか。 たとえば以下のようなSUBJECTだとすると・・ (1通目) Re: 注意:今月の残金が2013111100円です。 (2通目) 2013111100円が今月の残金です。 検索ワード”2013111100” では(2)しかヒットしなかったり・・。 日本語、英数字、両方で起こります。なので文字化けではなさそう。

  • Sendmailで送信すると本文にメールヘッダーが出る

    いつもお世話になります。 PerlでSendmail送信プログラムは何回か作ったことが有るのですが、いつもと同じように作っているつもりにも関わらず、送信されたメール本文の1~2行目に Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-2022-JP が表示されます。 コードは$mailtoや$mail_from、$mail_subjectなどをMIMEエンコードしてから下記の様なコードでメールヘッダーを作成し $header = <<END; To: $mailto Bcc:$mail From: $mail_from<$mail> Subject: $mail_subject Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-2022-JP END #メールの本文を下記のように作成 $body = <<END; メール本文 END $mbody=jcode::jis($body); #Sendmailで送信する。 open(MAIL, "| $SENDMAIL -i -t -f $mail") or die("ERROR: exec sendmail."); print MAIL $header, $mbody; close MAIL; というコード-です。 なにが原因かおわかりの方宜しくお願いします。

    • ベストアンサー
    • Perl
  • PHPから携帯へメール送信

    いつもお世話になっております。 PHPから携帯電話へ"絵文字付き"でメールを送るプログラムを作成している のですが、『base64_encode』等を使用して絵文字の表示までは行う事がで きました。 ですが、本文が途中で途切れてしまうのです・・・。 PHP側は、 $to = mb_convert_encoding(mb_decode_mimeheader($structure->headers['from']), 'SJIS', 'ISO-2022-JP'); $subject = mb_convert_encoding(mb_decode_mimeheader($structure->headers['subject']), 'SJIS', 'ISO-2022-JP'); (省略)  ・  ・ $body = $structure->body; $body = preg_replace('/\s*>\s.*/', '', $body); $body = mb_convert_encoding($body, 'SJIS', 'ISO-2022-JP'); //---------------------------------- // base64_encode //---------------------------------- $subject = "=?shift_jis?B?" . base64_encode($subject) . "?="; $body = base64_encode($body); //---------------------------------- // ヘッダを作成 //---------------------------------- $headers = "From: test@mail.com\n"; $headers .= "MIME-Version: 1.0\n"; $headers .= "Content-Type: text/plain; charset=Shift-JIS\n"; $headers .= "Content-Transfer-Encoding: base64"; //---------------------------------- // メール送信 //---------------------------------- $res = mail($to, $subject, $body, $headers);  ・  ・ (省略) 上記のように記述しています。 メールは送れます。絵文字も表示されます。ですが、本文が途中で途切れ てしまいます。 どなたかご教授をお願い致します。

    • ベストアンサー
    • PHP