忘れないように記録しとこ

Codeigniterのmailライブラリで送ったメールが、Gmailアプリで文字化ける

環境

Codeingiter: 2.x系

 

はじめに

先日、クライアントから一部の環境でメールが文字化けると連絡が入りました。
確認してみると、Gmailアプリで受け取ったメールに該当の現象が起きました。

「ふぁ?!」となる状況ながら調査しました。

 

原因

調査して分かったのは、Codeigniter 2.x系で送ったメールにこれが起きるようでした。
Codeigniter 3.x系では問題ないようです。(ライブラリの中身がまったくの別物)

■原因の箇所

private function _prep_q_encoding($str, $from = FALSE)
{
    $str = str_replace(array("\r", "\n"), array('', ''), $str);

    // Line length must not exceed 76 characters, so we adjust for
    // a space, 7 extra characters =??Q??=, and the charset that we will add to each line
    $limit = 75 - 7 - strlen($this->charset);

    // these special characters must be converted too
    $convert = array('_', '=', '?');

    if ($from === TRUE)
    {
        $convert[] = ',';
        $convert[] = ';';
    }

    $output = '';
    $temp = '';

    for ($i = 0, $length = strlen($str); $i < $length; $i++)
    {
        // Grab the next character
        $char = substr($str, $i, 1);
        $ascii = ord($char);

        // convert ALL non-printable ASCII characters and our specials
        if ($ascii < 32 OR $ascii > 126 OR in_array($char, $convert))
        {
            $char = '='.dechex($ascii);
        }

        // handle regular spaces a bit more compactly than =20
        if ($ascii == 32)
        {
            $char = '_';
        }

        // If we're at the character limit, add the line to the output,
        // reset our temp variable, and keep on chuggin'
        if ((strlen($temp) + strlen($char)) >= $limit)
        {
            $output .= $temp.$this->crlf;
            $temp = '';
        }

        // Add the character to our temporary line
        $temp .= $char;
    }

    $str = $output.$temp;

    // wrap each line with the shebang, charset, and transfer encoding
    // the preceding space on successive lines is required for header "folding"
    $str = trim(preg_replace('/^(.*)$/m', ' =?'.$this->charset.'?Q?$1?=', $str));

    return $str;
}

 

対応

以下のサイトを参考にしました。

https://www.bricoleur.co.jp/blog/archives/3480
https://qiita.com/seihowlow24/items/ca4b8fa00fab7a8160ee

qiita の記事は、かなり近かったのですが、管理人の環境では対応できませんでした。

■対応ソース

class MY_Email extends CI_Email {

    function __construct()
    {
        parent::__construct();
    }
    
	function message($body)
	{
		if (strtolower($this->charset) == 'iso-2022-jp')
		{
			$this->_body = mb_convert_encoding(stripslashes(rtrim(str_replace("\r", "", $body))), 'ISO-2022-JP', 'UTF-8');
		}
		else
		{
			$this->_body = stripslashes(rtrim(str_replace("\r", "", $body)));
		}

		return $this;
	}

	public function subject($subject)
	{
		$this->_headers['Subject'] = $subject;
		return $this;
	}

}

 

$this->load->library('email');
$config['wordwrap'] = FALSE;
$config['charset'] = 'ISO-2022-jp';
$this->email->initialize($config);

$subject = '件名';
$subject = "=?iso-2022-jp?B?".base64_encode(mb_convert_encoding($subject,"JIS","UTF-8"))."?=";

$this->email->from('[email protected]');
$this->email->to(set_value('mail'));
$this->email->subject($subject);
$this->email->message('本文');
$this->email->send();

いかがでしょうか?

正直、今回の対応のしかたには納得していません。
もっと良いやり方があったら教えてください。

そもそも2系なんて化石を使うなって話ですね。

今日はこの辺でー

この記事が気に入ったら
いいね ! しよう

Twitter で
Comments (2)
  1. jubilation より:

    I simply wanted to thank you so much once more. I’m not certain the things I
    could possibly have created in the absence
    of the actual smart ideas revealed by you on my situation. It actually was a alarming difficulty
    for me, however , looking at a professional tactic you dealt with that forced me to
    cry with gladness. Extremely happy for your service
    and even wish you really know what an amazing job you
    were accomplishing training other individuals all through a site.
    More than likely you haven’t come across any of us.

    1. 管理人 より:

      thank you for your comment.
      I would be fortunate if people were happy with my immature skill.
      Thank you again for giving me comments.

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください