解決方法をメモしておく。
CIのバージョンは3.1.6。
(バージョンはCodeIgniter.phpに書いてあるのを確認する)
#事象
codeigniterを使ってメール送信する機能を作ったが、iphoneのメーラーで受信した時に件名や本文が文字化けした。
ちなみにAndroidやPCのメーラー(thunderbirdとか)は文字化けしなかった。
元のソースはこれ
$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に定義
define('FROM_EMAIL', 'noreply@~'); //送信者アドレス
define('FROM_NAME', '送信者名'); //送信者名
define('FROM_SUBJECT', '登録が完了しました。'); //メールのタイトル
#修正してみた
まずは、件名と本文のmb_convert_encodingをやめることに。
UTF-8ならば表示されるはず…?
$this->email->subject(FROM_SUBJECT);
$this->email->message($data['message']);
で、メール送信してみたけど、まだ文字化けしてる。
調べてみるとCI_Email(Emailsystem\librariesにある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。
<?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にしてやれば良さそう。
// メールライブラリ
$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']);
ようやく文字化け解消!