Edited at

Codeigniterのメール送信で文字化けする(iphone)

More than 1 year has passed since last update.

解決方法をメモしておく。

CIのバージョンは3.1.6。

(バージョンはCodeIgniter.phpに書いてあるのを確認する)


事象

codeigniterを使ってメール送信する機能を作ったが、iphoneのメーラーで受信した時に件名や本文が文字化けした。

ちなみにAndroidやPCのメーラー(thunderbirdとか)は文字化けしなかった。

元のソースはこれ


Mail.php

$config = array(

'protocol' => 'sendmail',
'mailpath' => '/usr/sbin/sendmail',
'_encoding' => '7bit',
'charset' => 'ISO-2022-JP',
'newline' => '\r\n',
'mailtype' => 'text',
'validation' => FALSE,
'wordwrap' => FALSE,
'send_multipart' => FALSE
);
// メール送信
$this->load->library('parser');
// テンプレートに変数をアサイン
$data['message'] = $this->parser->parse('template/email/email_text', $data['email_text'], TRUE);
// メールライブラリ
$this->load->library('email',$config);
$this->email->set_newline("\r\n");
$this->email->from(FROM_EMAIL, mb_encode_mimeheader(FROM_NAME, "ISO-2022-JP", "UTF-8,EUC-JP,auto"));
$this->email->to($data['email']['user_email']);
$this->email->subject(mb_convert_encoding(FROM_SUBJECT, "ISO-2022-JP", "UTF-8,EUC-JP,auto"));
$this->email->message(mb_convert_encoding($data['message'], "ISO-2022-JP", "UTF-8,EUC-JP,auto"));
// メール送信
$mail_status = '1';
try{
if( !$this->email->send() ) {
log_message('debug', print_r($this->email->print_debugger(), true));
$mail_status = '9';
}
}catch( Exception $e ){
log_message('debug', print_r($e, true));
$mail_status = '9';
}

メールの件名はconstants.phpに定義


constants.php

define('FROM_EMAIL', 'noreply@~');    //送信者アドレス

define('FROM_NAME', '送信者名'); //送信者名
define('FROM_SUBJECT', '登録が完了しました。'); //メールのタイトル


修正してみた

まずは、件名と本文のmb_convert_encodingをやめることに。

UTF-8ならば表示されるはず…?


Mail.php

$this->email->subject(FROM_SUBJECT);

$this->email->message($data['message']);

で、メール送信してみたけど、まだ文字化けしてる。

調べてみるとCI_Email(Emailsystem\librariesにあるEmail.php)内で、なにやら問題があるよう。


Email.php

    public function subject($subject)

{
$subject = $this->_prep_q_encoding($subject); <--ココ
$this->set_header('Subject', $subject);
return $this;
}

public function message($body)
{
$this->_body = rtrim(str_replace("\r", '', $body)); <--ココ

if ( ! is_php('5.4') && get_magic_quotes_gpc())
{
$this->_body = stripslashes($this->_body); <--ココ
}

return $this;
}


これを使わないようにしたいので、Email.phpをオーバーライドしたMY_Email.phpを作成。

application\librariesに置けばOK。


MY_Email.php

<?php

defined('BASEPATH') OR exit('No direct script access allowed');

class MY_Email extends CI_Email {

public function __construct()
{
parent::__construct();
}

private function _set_header($header, $value)
{
$this->_headers[$header] = $value;
}

public function subject($subject)
{
$this->set_header('Subject', $subject);
return $this;
}

public function message($body)
{
$this->_body = $body;
return $this;
}
}


これで確認してみたところ、文字化けが解消!…と思いきや

ところどころにまだ文字化けが。

たぶん自動改行されてて、その改行コードが文字化けしてるっぽい。

Mail.phpのconfigで'wordwrap' => FALSE,にしてたけど、MY_Emailの中で親のコンストラクタ呼んでるから、configが効いてなかった。

emailライブラリをloadした後に自動改行をoffにしてやれば良さそう。


Mail.php

// メールライブラリ

$this->load->library('email',$config);
$this->email->set_newline("\r\n");
$this->email->set_wordwrap(FALSE); <--ここに追記
$this->email->from(FROM_EMAIL, mb_encode_mimeheader(FROM_NAME, "ISO-2022-JP", "UTF-8,EUC-JP,auto"));
$this->email->to($data['email']['user_email']);
$this->email->subject(FROM_SUBJECT);
$this->email->message($data['message']);

ようやく文字化け解消!