Zend_Mail を頑張って日本語対応してみた
タイトル通りがんばってみました。問題になってた長いSubjectでも文字化けはしません。
長いSubjectが文字化けするのは Zend_Mime::encodeBase64Header の第3引数の Zend_Mime::LINELENGTH(72) と第4引数のZend_Mime::LINEEND(\n)に問題があります。ヘッダを Base64 にエンコードする際に 72文字ごとに「\n」が入ってしまうことが原因でした。なので LINELENGTH の数を増やしてやるか、LINEEND を空文字を指定してやれば解決します。
解決できてない問題が1つあって、漢字の「松」が「毫」になるんですよねぇ。これは Zend_Mail::_filterName が余計なことをしやがってるせいです。
漢字の「松」は ISO-2022-JP では「e$B>>e(B」なのですが、これを「e$B]]e(B」に変換しやがるせいで化けてしまいます。これは正直どうしたものかと思ってて保留中。誰か詳しい方教えて下さい。
以下ソース
<?php require_once 'Zend/Mail.php'; class Japanese_Mail extends Zend_Mail { protected $_headerEncoding = Zend_Mime::ENCODING_BASE64; public function __construct($charset = 'iso-8859-1') { parent::__construct('ISO-2022-JP'); } public function addTo($email, $name='') { parent::addTo($email, mb_convert_encoding($name, 'ISO-2022-JP', mb_detect_encoding($name))); } public function addCc($email, $name='') { parent::addCc($email, mb_convert_encoding($name, 'ISO-2022-JP', mb_detect_encoding($name))); } public function setFrom($email, $name = null) { parent::setFrom($email, mb_convert_encoding($name, 'ISO-2022-JP', mb_detect_encoding($name))); } public function setSubject($subject) { parent::setSubject(mb_convert_encoding($subject, 'ISO-2022-JP', mb_detect_encoding($subject))); } public function setBodyText($txt, $charset = null, $encoding = Zend_Mime::ENCODING_QUOTEDPRINTABLE) { parent::setBodyText($txt, mb_convert_encoding($txt, 'ISO-2022-JP', mb_detect_encoding($txt)), Zend_Mime::ENCODING_7BIT); } public function setBodyHtml($html, $charset = null, $encoding = Zend_Mime::ENCODING_QUOTEDPRINTABLE) { parent::setBodyHtml($html, mb_convert_encoding($html, 'ISO-2022-JP', mb_detect_encoding($html)), Zend_Mime::ENCODING_7BIT); } protected function _encodeHeader($value) { if (Zend_Mime::isPrintable($value) === false) { if ($this->getHeaderEncoding() === Zend_Mime::ENCODING_QUOTEDPRINTABLE) { $value = Zend_Mime::encodeQuotedPrintableHeader($value, $this->getCharset(), Zend_Mime::LINELENGTH, ''); } else { $value = Zend_Mime::encodeBase64Header($value, $this->getCharset(), Zend_Mime::LINELENGTH, ''); } } return $value; } protected function _formatAddress($email, $name) { if ($name === '' || $name === null || $name === $email) { return $email; } else { $encodedName = $this->_encodeHeader($name); $format = '"%s" <%s>'; return sprintf($format, $encodedName, $email); } } }
Free source code hosting for Git and Mercurial by Bitbucket に置きました。