mb_encode_mimeheader()は、mbstring.internal_encodingから第二引数の文字コード、またはmbstring.languageで指定した言語に合った文字コード(JapaneseならISO-2022-JP)に変換した上でbase64へエンコード、エンコード情報を付加します。
よって、レンタルサーバでphp.iniの設定が不十分な場合、個別に設定したい場合は、関数をコールする前にmb_language()、mb_internal_encoding()で値を設定する必要があります。
(かなり)よく見かけますが、第一引数に渡す文字列をISO-2022-JPへ変換する必要はありません。
正しくは必要がないのではなく、やってはいけません。
ダメ、絶対。
<?php
mb_language('ja');
mb_internal_encoding('UTF-8');
$subject = '十分に長いsubjectでのテストを行います、まる';
echo mb_encode_mimeheader($subject) . "\n";
echo mb_encode_mimeheader(mb_convert_encoding($subject, 'ISO-2022-JP', 'UTF-8')) . "\n";
?>
結果。
=?ISO-2022-JP?B?GyRCPT1KLCRLRDkkJBsoQnN1YmplY3QbJEIkRyROJUYlOSVIJHIbKEI=?=
=?ISO-2022-JP?B?GyRCOVQkJCReJDkhIiReJGsbKEI=?=
=?ISO-2022-JP?B?GyRCPT1KLCRLRDkkJBsoQnN1YmplY3QbJEIkRyROJUYlOSVIJHI5VCQk?=
=?ISO-2022-JP?B?JF4kOSEiJF4kaxsoQg==?=
なんか後半が違います。
分割される長さでないと問題が発生しないのが問題なような気もしますが。
mb_decode_mimeheader()は大方の予想通りmb_encode_mimeheader()と逆の動作をしそうです。
<?php
mb_language('ja');
mb_internal_encoding('UTF-8');
$subject = '十分に長いsubjectでのテストを行います、まる';
$utf = mb_encode_mimeheader($subject);
$iso = mb_encode_mimeheader(mb_convert_encoding($subject, 'ISO-2022-JP', 'UTF-8'));
echo mb_decode_mimeheader($utf) . "\n";
echo mb_decode_mimeheader($iso) . "\n";
?>
結果。
十分に長いsubjectでのテストを行います、まる
十分に長いsubjectでのテストを行い$^$9!"$^$k
!
そもそも、mb_encode_mimeheader()を通した段階で結果が違うのがおかしいですね。
<?php
mb_language('ja');
mb_internal_encoding('UTF-8');
$subject = '十分に長いsubjectでのテストを行います、まる';
mb_internal_encoding('ISO-2022-JP');
$iso = mb_encode_mimeheader(mb_convert_encoding($subject, 'ISO-2022-JP', 'UTF-8'));
echo $iso . "\n";
mb_internal_encoding('UTF-8');
echo mb_decode_mimeheader($iso) . "\n";
?>
結果。
=?ISO-2022-JP?B?GyRCPT1KLCRLRDkkJBsoQnN1YmplY3QbJEIkRyROJUYlOSVIJHIbKEI=?=
=?ISO-2022-JP?B?GyRCOVQkJCReJDkhIiReJGsbKEI=?=
十分に長いsubjectでのテストを行います、まる
mb_encode_mimeheader()に渡す文字列はISO-2022-JPに変換するな。