
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?=」を自動的に付加していることにありそうだということまでは想像がついたのですが,これの回避方法が分かりません。
メールヘッダーの簡単な解説を含めて,この場合の回避方法を教えていただきたいです。よろしくお願いします。
投稿日時 - 2010-09-09 16:35:13
■メールに関して
私は、
>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で内容を追うのはとても大変でした)
がんばってください。
投稿日時 - 2010-09-13 00:18:30
hogehoge78さん,ありがとうございます。
Email.phpをのぞいてみました。なるほど,_prep_q_encodingというプライベートメソッドを定義して,これを使ってSubjectをエンコードしていたのですね。そこで強制的にQuoted Printable形式を指定する’Q’が挿入されていたみたいですね。
MYクラスを作って,この中でプライベートメソッド_prep_b_encodingを定義し,base64でサブジェクトをエンコードするようにして,これ以外にエンコードしないという方法でやってみようと思います。
また,セッションについてですが,HTMLのキャッシュを残さない方法を講じる必要があるとのことですが,勉強していろいろと試してみたいと思います。先が見えたような気がします。
私も,数々(40冊は超えると思います。)のPHP関係やHTML関係の本を持っていますが,キャッシュについては見落としていました。(というか,この部分を強調している本はあまりなかったように思います。)以前に同様の質問を,様々なサイトにアップしましたが,これほど適切なお答えはありませんでした。
hogehoge78さん,本当にありがとうございました。
それから,「CodeIgniter徹底入門」とても良い本だと思います。必要な人があれば,強く勧めていきたいと思います。
これからも,このような本がたくさん出版されるといいなと思っています。
また,何かありましたらよろしくお願いします。
投稿日時 - 2010-09-13 01:40:01
このQ&Aは役に立ちましたか?
6人が「このQ&Aが役に立った」と投票しています
回答(7)
該当する書籍は、たまたま手元に持っていたのですが、
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クラスとか作って継承クラス作っているのを忘れていないかとか、チェックしてみてください。
投稿日時 - 2010-09-12 19:09:41
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さん,どうかよろしくお願い申し上げます。
投稿日時 - 2010-09-12 23:26:17
mb_convert_mimeheaderは正しい挙動をしています。
mimeヘッダはある程度長い文字がある場合は、自動的に文字を分割して、且つ、CR+LFで改行します。
また、mb_convert_mimeheaderは、内部文字コードを第二引数で指定した文字コードに変換をしてコンバートを行いますので、
<?php
mb_internal_encoding("質問者さんがPHPファイルに記述している文字コード");
$subject = mb_convert_mimeheader("タイトル", "ISO-2022-JP");
?>
などとする必要があります。
投稿日時 - 2010-09-11 01:47:43
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ライブラリが原因なのでしょうか?
投稿日時 - 2010-09-12 12:44:11
subjectのISO-2022-JP変換には mb_encode_mimeheader()関数を使います。
詳細はマニュアルを見てください。
投稿日時 - 2010-09-09 21:38:39
ありがとうございます。
実は,下記のように
$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パラメータで指定してやる必要があるのでしょうか?まだやってみてませんが…?いかがでしょうか?
投稿日時 - 2010-09-09 22:13:38
タイトルは、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);
投稿日時 - 2010-09-09 17:32:22
ご回答ありがとうございます。
早速,次のようにしてやってみました。
$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が標準で付加する仕様になっているのでしょうか?この部分を付加させないようにする,引数は無いのでしょうか?
よろしければ,この後のご指導をよろしく願いします。
投稿日時 - 2010-09-09 20:46:17