Asial Blog

Recruit! Asialで一緒に働きませんか?

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

カテゴリ :
バックエンド(プログラミング)
タグ :
Tech
symfony
Mail
Swift
2008.12.03 やっぱり使い方を間違っていなかったようなので、再修正です。田舎の開発者さんご指摘ありがとうございました。

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


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

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

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

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

  1. <?php
  2. // ...省略
  3. // 2008.08.28 修正
  4. /*
  5. $msg = new Swift_Message(
  6.   'サブジェクト',
  7.   mb_convert_encoding('本文', 'JIS', 'UTF-8'),
  8.   'text/plain',
  9.   '7bit',
  10.   'iso-2022-jp'
  11. );
  12. */
  13. // 2008.12.03 再修正
  14. /*
  15. $msg = new Swift_Message(
  16.   'サブジェクト',
  17.   '本文',
  18.   'text/plain',
  19.   'iso-2022-jp',
  20.   '7bit'
  21. );
  22. */
  23. $msg = new Swift_Message(
  24.   'サブジェクト',
  25.   mb_convert_encoding('本文', 'JIS', 'UTF-8'),
  26.   'text/plain',
  27.   '7bit',
  28.   'iso-2022-jp'
  29. );
  30. $conn = new Swift_Connection_SMTP('localhost');
  31. $mailer = new Swift($conn);
  32.  
  33. $mailer->send($msg, 'to@example.com', 'from@example.com');
  34. // ...省略

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

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

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

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

  1. <?php
  2. // ...省略
  3. /*
  4. $msg = new Swift_Message(
  5.   mb_convert_encoding('サブジェクト', 'JIS', 'UTF-8'),
  6.   mb_convert_encoding('本文', 'JIS', 'UTF-8'),
  7.   'text/plain',
  8.   '7bit',
  9.   'iso-2022-jp'
  10. );
  11. */
  12. /*
  13. $msg = new Swift_Message(
  14.   mb_convert_encoding('サブジェクト', 'JIS', 'UTF-8'),
  15.   '本文',
  16.   'text/plain',
  17.   'iso-2022-jp',
  18.   '7bit'
  19. );
  20. */
  21. $msg = new Swift_Message(
  22.   mb_convert_encoding('サブジェクト', 'JIS', 'UTF-8'),
  23.   mb_convert_encoding('本文', 'JIS', 'UTF-8'),
  24.   'text/plain',
  25.   '7bit',
  26.   'iso-2022-jp'
  27. );
  28. $msg->headers->setCharset('ISO-2022-JP');
  29. // ...省略

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

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

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

  1. Subject: =?ISO-2022-JP?B?GyRCJTUlViU4JSclLyVIJTUlViU4JSclLyVIJTUlViU4?=
  2.  =?ISO-2022-JP?B?JSclLyVIGyhC?=

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

  1. Subject: =?ISO-2022-JP?B?GyRCJTUlViU4JSclLyVIJTUlViU4JSclLyVIJTUlViU4GyhC?=
  2.  =?ISO-2022-JP?B?GyRCJSclLyVIGyhC?=

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

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

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