通知メールの本文が文字化けする

お世話になっております。

zabbix v3.0.8
メール通知はsendmessage_smtp_php.sh
smtpサーバーはsendgridサービス

を使用しています。

通知メールの本文内に「ー」があると文字化けしてしまいます。
WebConsole上もDBも文字化けせずに出力、格納されていて、zabbix_server.log上のメール送信ログも文字化けせずに、出力されています。
sendmessage_smtp_php__iso-2022-jp-ms_for_after_PHP5.2.1.shを使用してみましたが、変わりませんでした。

英語のみのメールの場合は以下の文字コードが使用されていますが、

before MAIL_TO :ASCII
before MAIL_SUBJECT :ASCII
before MAIL_MESSAGE :ASCII
after MAIL_TO :ASCII
after MAIL_SUBJECT :ASCII
after MAIL_MESSAGE :ASCII

日本語が混ざると以下のように、MAIL_MESSAGEだけがUTF-8になってしまいます。

before MAIL_TO :ASCII
before MAIL_SUBJECT :ASCII
before MAIL_MESSAGE :UTF-8
after MAIL_TO :ASCII
after MAIL_SUBJECT :ASCII
after MAIL_MESSAGE :UTF-8

シェル内の

$mailer->Body = mb_convert_encoding($MAIL_MESSAGE,"JIS","UTF-8");

が文字化けの原因だと特定したのですが、どのように修正したら良いでしょうか?

よろしくお願いします。

コメント表示オプション

お好みのコメント表示方法を選び「設定の保存」をクリックすると変更が反映されます。
ユーザー TNK の写真

CentOS 7.3上の標準のPHP 5.4.16で実行してみましたが、記載頂い
た「ー」(長音、UTF-8: E28095)であれば、文字化けは発生せず、
例えば、「メール」とか「サーバー」という文字列が含まれていて
も文字化けなくメール送信ができています。

フォントによっては、「ー」に似ているけれども異なる文字がある
ので、その文字がUTF-8からISO-2022-JPに変換する際に文字のマッ
ピングが定義されていないことで文字化けが発生しているかもしれ
ません。

ISO-2022-JPに含まれないような文字を使用されたい場合は、UTF-8
で送るなどの検討も必要かもしれません。
とはいえ、メールを受け取るシステム側がUTF-8のメールを正常に
受け取れないのであれば、やはりメッセージ内で使用する文字に注
意が必要です。

ご確認ください。

広瀬です

いちを補足として投稿させていただきます。
ISO-2022-JPとJISは似て非なるモノです(具体的には半角カタカナの変換に違いがでます)
なので、どちらかと言えば修正版のISO-2022-JP-MSを使う方が未だスマートです。

TNKさんも指摘されている通り、「ー」に似た文字の使用か、または前後に何らか文字化け
起こす様な文字が連続しているなどが考えられます。
他、メーラーによる誤差も出てきます。たとえば、Thunderbirdでは全部UTF-8のメールでも
日本語表示してくれたりします(スクリプト使わず、デフォルトのSMTP利用時)。
携帯、スマホも誤差修正が出来るもの、出来ないモノがあります。

若干、公開されているPHPスクリプトはパワープレー否めないので、個人的には修正してい
ますが、本文の変換処理部分はそのままですので、前述の問題が大きいのでは無いでしょうか?

ユーザー yudai の写真

回答ありがとうございます。

フォーラムで過去ログを確認したのですが、
DBのCharsetが以下のようになっていることが原因だと考えられますか?

MariaDB [(none)]> show variables like 'char%'
-> ;
+--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | latin1 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | latin1 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+

ユーザー TNK の写真

データベースのcharacter setがlatin1では、メール送信以外でも
文字化けが発生すると思います。
Zabbix用データベースのcharacter setは、utf8にしてください。

ユーザー yudai の写真

TNKさん、広瀬さん、
回答ありがとうございました。解決しました!

画面とDBがutf-8なので、送信時もutf-8でやればいいのでは?
と思い、以下3点をutf-8で扱うよう変更しました。

・mb_internal_encoding
・class PHPMailer_JP extends PHPMailer {
public $CharSet = "UTF-8";
public $Encoding = 'base64';
}
・$mailer->Body = $MAIL_MESSAGE;

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

mb_language("japanese");
mb_internal_encoding("UTF-8");
require("phpmailer/class.phpmailer.php");

/* setting */
$MAIL_FROM = "zabbix@iotapbatch01";
$MAIL_FROMNAME = "Zabbix 障害通知";
$MAIL_SMTP_HOST = 'せんどぐりっど';
$MAIL_SMTP_USER = 'ゆーざー';
$MAIL_SMTP_PASS = 'ぱすわーど';
/* setting */

$MAIL_TO = $argv[1];
$MAIL_SUBJECT = $argv[2];
$MAIL_MESSAGE = $argv[3];

class PHPMailer_JP extends PHPMailer {
public $CharSet = "UTF-8";
public $Encoding = 'base64';
}

$mailer = new PHPMailer_JP();
$mailer->IsSMTP();

$mailer->Host = $MAIL_SMTP_HOST;
$mailer->SMTPAuth = true;
$mailer->Username = $MAIL_SMTP_USER;
$mailer->Password = $MAIL_SMTP_PASS;

$mailer->From = $MAIL_FROM;
$mailer->AddAddress($MAIL_TO);

$mailer->FromName = mb_encode_mimeheader(mb_convert_encoding($MAIL_FROMNAME,"ISO-2022-JP-MS","UTF-8"),"ISO-2022-JP-MS");
$mailer->Subject = mb_encode_mimeheader(mb_convert_encoding($MAIL_SUBJECT,"ISO-2022-JP-MS","UTF-8"),"ISO-2022-JP-MS");
$mailer->Body = $MAIL_MESSAGE;
// $mailer->AddReplyTo($email, $from);

if(!$mailer->Send()){
print "failed: " . $mailer->ErrorInfo . "\n";
}else{
print "success" . "\n";
}

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

広瀬です。

恐らくお使いのメーラーがUTF-8に強いものなのでしょう。
ZABBIXの本旨外れますが参考までに一点申し上げておきますが、上記ではユーザフレンドリーでは
ありませんので根本的な解決にはなりません。恐らく何れかのメーラー、携帯、スマホでは間違いなく文
字化けとなります。
主要なメーラーからマイナーなメーラー、Webメール、ガラケー、スマホ100台は下らないほどの端末で
検証を行い、文字化け回避してきたので断言できます。

 ※細かい事だが、データ型(文字集合)と符号方式は混同しちゃうとまずいです
   base64も結果的には7bit化されますんで、Encodingの値がbase64は意味が無い

ただ、まぁこの辺最近ISO-2022-JPじゃなくてもよくね?っていう風潮もあるので、内輪的なものならば
議論とする必要も無いとは思います。確かに手元に届くメールは文字コードごった煮状態ですし・・・

「送るときは保守的に。受ける時はリベラルに」・・・・というのが信条ですんで、あしからず。