PHPで構築されたメールシステムで、UTF-8にて格納されたデータを取得して
メールデータを作成する部分があります。
以下のように件名や差出人・宛先をISO-2022-JPにエンコードするのですが、
何故か宛先名(name)のみがISO-8859-1(latin1)にエンコードされてしまいます。
//Subject
$subject = mb_convert_encoding($subject, "ISO-2022-JP", "UTF-8");
//FROM
$from_data['name'] = mb_convert_encoding($from_data['name'], "ISO-2022-JP", "UTF-8");
//TO・CC・BCC
foreach($send_data as $type => $data){
for($i=0; $i<count($data[$type]); $i++){
$send_data[$type][$i]['name'] = mb_convert_encoding($send_data[$type][$i]['name'], "ISO-2022-JP", "UTF-8");
}
}
最終的に生成されたメールのヘッダはコメントに記したとおりです。
宛先部分のみがループ処理を挟んでいますが(ToやCc、Bccで複数あり得るので…)、
そのあたりが怪しいのでしょうか?
上記ソースから心当たりがあれば、ご教示いただけると幸いです。
よろしくお願いいたします。
なお、PHPは5.2.13、データベースはMySQL5.1.50を使用しています。
無事に解決したという事で良かったです。
$send_data = array( "TO"=>array( 0=>array( "name"=>"副管理人","email"=>"member@mail.example.jp" ) ), "CC"=>array( 0=>array( "name"=>"メンバー1", "email"=>"member001@mail.example.jp" ), 1=>array( "name"=>"メンバー2", "email"=>"member002@mail.example.jp" ), 2=>array( "name"=>"メンバー3", "email"=>"member003@mail.example.jp" ) ), "BCC"=>array( ) );
$send_dataが上記のようになっている場合、次の処理を行うと「count($data[$type])」でカウントが0になってしまいますので、forの中が処理されません。
foreach($send_data as $type => $data){ for($i=0; $i<count($data[$type]); $i++){
「foreach($send_data as $type => $data)」としていますので、「count($send_data[$type])」あるいは「count($data)」に変更すると、正しい個数を取得できます。
ちょっとややこしいですね・・・
echo "<pre>\$data:"; print_r($data); echo "</pre>\n";
上記のように出力して確認すると、目的の値にアクセスできているか、若干分かりやすくなると思います。
motokun44さんがコメントで指摘していますが、「mb_send_mail()」を使用する場合は、「mb_encode_mimeheader()」だけ使用すれば良いようです。
http://www.asahi-net.or.jp/~wv7y-kmr/memo/php_mbstring.html#mb_s...
※mail関数を使用する場合は、「mb_convert_encoding()」も必要です。
mimeheader抜けてませんか?
//Subject $subject = mb_convert_encoding($subject, "ISO-2022-JP", "UTF-8"); $subject = mb_encode_mimeheader($subject,"ISO-2022-JP");
回答ありがとうございます。
mimeheaderは上記の処理の後にまとめておこなっています。
print $send_data[$type][$i]['name'];
で出力して確認してみては?
回答ありがとうございます。
ご指摘のとおり、配列の中身を確認してみたところ、
ループ処理での配列要素の取得の方に問題があることが分かりました。
ISO-8859-1になっていたので、てっきりエンコードの問題かと思いましたが…。
有益なご指摘、感謝します。
メールヘッダの変換には mb_encode_mimeheader() を使うのが便利です。
この関数はマルチバイト文字をiso-2022-jpに変換してbase64encodeするものですから引数は変換対象文字列だけです。
$subject = mb_encode_mimeheader($subject);
if(preg_match('/(.+)(<.+@.+>)/',$from_data['name'],$x))
$from_data['name'] = mb_encode_mimeheader($x[1]).$x[2];
To,Cc,Bccについても同様。
回答ありがとうございます。
mimeheaderは上記の処理の後にまとめておこなっています。
無事に解決したという事で良かったです。
$send_data = array( "TO"=>array( 0=>array( "name"=>"副管理人","email"=>"member@mail.example.jp" ) ), "CC"=>array( 0=>array( "name"=>"メンバー1", "email"=>"member001@mail.example.jp" ), 1=>array( "name"=>"メンバー2", "email"=>"member002@mail.example.jp" ), 2=>array( "name"=>"メンバー3", "email"=>"member003@mail.example.jp" ) ), "BCC"=>array( ) );
$send_dataが上記のようになっている場合、次の処理を行うと「count($data[$type])」でカウントが0になってしまいますので、forの中が処理されません。
foreach($send_data as $type => $data){ for($i=0; $i<count($data[$type]); $i++){
「foreach($send_data as $type => $data)」としていますので、「count($send_data[$type])」あるいは「count($data)」に変更すると、正しい個数を取得できます。
ちょっとややこしいですね・・・
echo "<pre>\$data:"; print_r($data); echo "</pre>\n";
上記のように出力して確認すると、目的の値にアクセスできているか、若干分かりやすくなると思います。
motokun44さんがコメントで指摘していますが、「mb_send_mail()」を使用する場合は、「mb_encode_mimeheader()」だけ使用すれば良いようです。
http://www.asahi-net.or.jp/~wv7y-kmr/memo/php_mbstring.html#mb_s...
※mail関数を使用する場合は、「mb_convert_encoding()」も必要です。
さらに情報を付加していただき、ありがとうございました。
「mb_encode_mimeheader()だけ」も試してみます。
さらに情報を付加していただき、ありがとうございました。
「mb_encode_mimeheader()だけ」も試してみます。