質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.13%

PHPでmb_encode_mimeheaderを使うと半角カタカナが文字化けする

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 3,367

kumakumatan

score 167

php-5.5.27
Windows2008R2

mb_send_mailにて本文、題名などに半角カタカナを利用すると、「????」となって
しまいます。

$header = mb_convert_encoding($header, 'ISO-2022-JP-MS', 'UTF-8' );
や
$header = mb_convert_kana($header, "KV", "utf-8");
メール送信
mb_send_mail ( $to,$sub,$msg,$header)


をしても「???」となってしまいます。
どのようにしたら対処できますでしょうか?

下記にソースコードを記載します。

<?php

setlocale(LC_CTYPE, 'Japanese_Japan.932'); //locale設定

mb_language("Japanese");
mb_internal_encoding("SHIFT-JIS");


require_once ( 'xxx.inc.php' );

$mysqli = new mysqli(HOST_IP, USER_NAME, USER_PASSWORD, DB_NAME);

   // SQLを実行します(ユーザ名・パスワード検索)。 
if (!$select = mysqli_query($mysqli, "SELECT * FROM db_user")) {

header("Location:./ERROR/db-error.php");

   exit();
}


//$result = mysqli_query($mysqli, "SELECT Address FROM mail");
//if (!$result) {
//    echo '只今、システムが利用できません。管理者にお問合せ下さい。';
//    exit;
//}

//  SQLの実行(SELECT)
$sql = "SELECT * FROM mail where FLG = '0' or '1' ";
if ($result = $mysqli->query($sql)) {
    // 連想配列を取得
    while ($row = $result->fetch_assoc()) {
    //    echo $row["Address"] . $row["JIGMEK"] . "<br>";
    //echo $row["Address"] . "<br>";
    $email[] = $row["Address"];
    $send = implode(",", $email);

    }
    // 結果セットを閉じる
    $result->close();
}

//  SQLの実行(SELECT)
$sql1 = "SELECT * FROM mail where FLG = '1'";
if ($result1 = $mysqli->query($sql1)) {
    // 連想配列を取得
   while ($row = $result->fetch_assoc()) {
    //    echo $row["Address"] . $row["JIGMEK"] . "<br>";
    //echo $row["Address"] . "<br>";
    $email2[] = $row["Address"];
    $sendkanri = $email2;
    }
    // 結果セットを閉じる
    $result1->close();
}


//  SQLの実行(カウント)
//echo "rows=" . mysqli_num_rows($result);
//MySQL から切断
//    $mysqli->close(); 

//echo $send;


//dateでフォーマットを指定して日付を取得 
//5.1.0からタイムゾーンを設定する必要がある。
date_default_timezone_set('Asia/Tokyo'); 
$systemDate = date("Y/m/d/ H:i:s"); 

$send = $send ."," .$MAIL;


$msg = "お疲れ様です。";

//////////0x5c対応//////////
//エスケープ文字削除
$FILENAME2 = stripcslashes($FILENAME2);
//////////0x5c対応//////////



//$array[] = "アップロードされました。";
//$array[] = "";
//$array[] = "テスト";
//$array[] = "";
//$array[] = "担当者";
$msg .= "\r\n";
$msg .= "\r\n";
$msg .= "アップロードされました。";
$msg .= "\r\n";
$msg .= "\r\n";
$msg .= "  ■アップロード日付:$systemDate";
$msg .= "\r\n";
$msg .= "\r\n";
$msg .= "  ■タイトル:$test";
$msg .= "\r\n";
//$msg .= "\r\n";
//$msg .= "  ■会社名:$test1";
//$msg .= "\r\n";
$msg .= "\r\n";
$msg .= "  ■送信者:$test2";
$msg .= "\r\n";
$msg .= "\r\n";
$msg .= "  ■アップロードファイル名:$FILENAME2";
$msg .= "\r\n";
$msg .= "\r\n";
$msg .= "  ■ダウンロード先:テストURL";
$msg .= "\r\n";
$msg .= "\r\n";
$msg .= "\r\n";
$msg .= "\r\n";
$msg .= "ご確認をお願いします。";

$to = "$send";
$sub = "資料【" .$test ."】アップロード完了";


$header = "From: " .mb_encode_mimeheader("テスト") ."<test@xx.dxxx.xx.jp>";

$header.= "\n";
$header.= "Bcc:xxxx@xx.xxx.xx.xx";


// 件名をJISに変換
$sub = mb_convert_encoding($sub,"SHIFT-JIS");
// 本文をJISに変換
//$header = mb_convert_encoding($header,"SHIFT-JIS");
$header = mb_convert_encoding($header, 'ISO-2022-JP-MS', 'SHIFT-JIS' );
//$header = mb_convert_kana($header, "KV", "SHIFT-JIS");


if (!$mailsend = mb_send_mail ( $to,$sub,$msg,$header)){

   $query = "INSERT INTO mail_log(date, test, test2, test3, test4, test5) values('$systemDate', '$test2', '$test3', '$test4', '$test5', 'NG')";
   $result = $mysqli -> query($query);
   $mysqli->close();

   }else{

   $query = "INSERT INTO mail_log(date, test, test2, test3, test4, test5) values('$systemDate', '$test2', '$test3', '$test4', '$test5', 'OK')";
   $result = $mysqli -> query($query);
   $mysqli->close();

   }

?>

お時間のある時、ご教授をお願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+1

$header = mb_convert_encoding($header, 'ISO-2022-JP-MS', 'UTF-8' );

こちらはISO-2022-JP-MSですし、半角は半角のままになりますね。

$header = mb_convert_kana($header, "KV", "utf-8");

こちらはUTF-8ですよ?
文字コードがバラバラですから、どうなっているのかわかりません。
本当にinternal encodingはUTF-8ですか?

どういう流れで使っているのか分からないので、何とも言えないです。
コードを切り出す際は、実際に症状が出ている状態で最小のコードを作っていただくと回答しやすいです。

追記

やっぱり実際のコードとは違いましたね。

$header = "From: " .mb_encode_mimeheader("テスト") ."<test@xx.dxxx.xx.jp>";

ここでmb_encode_mimeheaderに入れている「テスト」が実は半角なんですね?
mb_encode_mimeheaderはinternal encodingのSJISでmimeエンコードされてしまいます。

$header = "From: " .mb_encode_mimeheader("テスト", 'ISO-2022-JP-MS') ."<test@xx.dxxx.xx.jp>";

としてみてはどうでしょうか?

あと、奇妙に思うのは、全体的にSJISで文字コードを統一しておられると思います。
ですので、subjectや本文は文字コードのコンバートがいらないと思います。mb_send_mailが勝手に、SJISからISO-2022-JPに変換します。

さらに追記

Wikipedia ISO-2022-JP より

また、符号化方式名をISO-2022-JPとしているのに、文字集合としてはJIS X 0212(補助漢字)やJIS X 0201の片仮名文字集合(いわゆる半角カナ)をも符号化している例があるが、ISO-2022-JPではこれらの文字を許容していない。これらの符号化は独自拡張の実装であり、中にはISO/IEC 2022の仕様に準拠すらしていないものもある。従って受信側の電子メールクライアントがこれらの独自拡張に対応していない場合、その文字あるいはその文字を含む行、時にはテキスト全体が文字化けすることがある。

となっていますので、mbstringが半角カナをうまくISO-2022-JPにコンバートできなくても、しょうがないような気がします。(mb_send_mailはISO-2022-JPにコンバートします。MS独自拡張ではありません)
どうしても、半角カナが送れないと嫌だ、という場合は、ISO-2022-JP-MSにすべてコンバートした上で、mailで送ればいいと思いますよ。

また、

$msg = mb_convert_kana($msg, "KV", "SHIFT-JIS");

とやって、半角カナから全角カナにコンバートしてやっても化けるとなると、おかしなことですね。
提供されているコードではそのようにしているところがありませんでした。
(やろうとしているのは$headerに対してです。コメントアウトされてますけど)

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/09/29 19:13

    コードを作成して、質問画面にアップロードしました。
    お時間のあるときご教授をお願いします。

    キャンセル

  • 2016/09/29 19:52

    ご回答ありがとうございます。
    実際は本文の文字(変数)に半角カナだと文字(?)になってしまいます。

    キャンセル

  • 2016/09/30 10:51

    ご回答ありがとうございます。半角カナを全角カナに変換する事で解決しました。
    //半角カナを全角カナに変換する
    $TEST = mb_convert_kana($TEST, 'K');
    $TEST2 = mb_convert_kana($TEST2, 'K');
    で対応できました。
    ありがとうございました。

    キャンセル

0

PHPでJIS以外の文字を文字化けせずに日本語メールを送る方法
いわゆる半角カナや種依存文字などをメールで送信する方法
あたりが使えるのでは?

ちょっと古い話ですが、UNIX系では半角カタカナは文字化けし易いので全角に変換して使うことが多かったようで、半角カタカナも全角カタカナも1文字3バイト使うので容量を節約できるメリットもなくなったので、半角カタカナは使わない、使っても勝手に全角変換するってユーザーもあります。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.13%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る