symfonyでSwift Mailerを使用する際の注意点

2008.12.03 やっぱり使い方を間違っていなかったようなので、再修正です。田舎の開発者さんご指摘ありがとうございました。

2008.08.28 Swift_Messageの使い方を間違えるという、とっても初歩的なミスをしていたので、修正しました。 shuwat さんありがとうございました

先日のsymfonyのjpMailPlugin(メール送信プラグイン)の使い方のまとめのコメントで、Swift Mailerについてshuwatさんがコメントで言及されていたので、Swift Mailerについて軽くふれておきます。

とりあえず、symfonyのCookbookに書いてある通りに進めればできます。

symfony1.0 であってもgetPresentationFor()メソッドを使用して同様にメール送信することもできます。

SMTPを使用したメールのであれば、以下のコードで送信することができると思います。


<?php
// ...省略
// 2008.08.28 修正
/*
$msg = new Swift_Message(
  'サブジェクト',
  mb_convert_encoding('本文', 'JIS', 'UTF-8'),
  'text/plain',
  '7bit',
  'iso-2022-jp'
);
*/
// 2008.12.03 再修正
/*
$msg = new Swift_Message(
  'サブジェクト',
  '本文',
  'text/plain',
  'iso-2022-jp',
  '7bit'
);
*/
$msg = new Swift_Message(
  'サブジェクト',
  mb_convert_encoding('本文', 'JIS', 'UTF-8'),
  'text/plain',
  '7bit',
  'iso-2022-jp'
);
$conn = new Swift_Connection_SMTP('localhost');
$mailer = new Swift($conn);
$mailer->send($msg, 'to@example.com', 'from@example.com');
// ...省略

ソースコードがUTF-8で記述されていれば、これで本文が ISO-2022-JP のメールが送信されるのですが、SubjectヘッダーはUTF-8の状態で送信されます。そのため、メールのソースを見ると以下のようになってしまいます。


Subject: =?utf-8?B?44K144OW44K444Kn44Kv44OI?=

Thunderbirdの場合、うまくデコードしてくれるのですが、その他のメーラーでもデコードできるかどうかは不明です。特に携帯メールの場合は怪しいと思います(おそらく絵文字を件名に入れたりはできないかと思われます)。

なお、ISO-2022-JP の件名を作成することも可能で、以下のようにします。


<?php
// ...省略
/*
$msg = new Swift_Message(
  mb_convert_encoding('サブジェクト', 'JIS', 'UTF-8'),
  mb_convert_encoding('本文', 'JIS', 'UTF-8'),
  'text/plain',
  '7bit',
  'iso-2022-jp'
);
*/
/*
$msg = new Swift_Message(
  mb_convert_encoding('サブジェクト', 'JIS', 'UTF-8'),
  '本文',
  'text/plain',
  'iso-2022-jp',
  '7bit'
);
*/
$msg = new Swift_Message(
  mb_convert_encoding('サブジェクト', 'JIS', 'UTF-8'),
  mb_convert_encoding('本文', 'JIS', 'UTF-8'),
  'text/plain',
  '7bit',
  'iso-2022-jp'
);
$msg->headers->setCharset('ISO-2022-JP');
// ...省略

これでSubjectヘッダーは以下のように変更されます。


Subject: =?ISO-2022-JP?B?GyRCJTUlViU4JSclLyVIGyhC?=

一見これでうまくいったかのように見えるのですが、件名が長い場合の折り返し処理で不都合が生じます。たとえば、「サブジェクトサブジェクトサブジェクト」とした場合には件名が文字化けを起こします。そのときのメールヘッダーは以下のようになります。


Subject: =?ISO-2022-JP?B?GyRCJTUlViU4JSclLyVIJTUlViU4JSclLyVIJTUlViU4?=
 =?ISO-2022-JP?B?JSclLyVIGyhC?=

なお、mb_encode_mimeheader()を使用すると以下のようになります。


Subject: =?ISO-2022-JP?B?GyRCJTUlViU4JSclLyVIJTUlViU4JSclLyVIJTUlViU4GyhC?=
 =?ISO-2022-JP?B?GyRCJSclLyVIGyhC?=

JISコードで使用するエスケープシーケンスを各行の最後に追加していないため、このようなことが起きてしまいます。

Swift_Mailer の内部的な処理としてヘッダーのエスケープ処理(Swift_Message_Headers)が記述されているので、mb_encode_mimeheader()を使用してエンコードする処理に変更する必要があります(もしくはSwift_Message_Headersを直接変更してしまいます)。

とは言ってもそこまでする必要はあまりないかと思います。普通に symfony1.1 でも jpMail を使用できないことはないので、そちらを使った方が今のところは良いと思います。