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

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

ただいまの
回答率

90.45%

  • PHP

    24602questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

  • メール

    318questions

    メールは、コンピュータネットワークを利用し、 情報等を交換する手段のことです。

  • UTF-8

    129questions

    UTF-8は8ビット符号単位の文字符号化形式及び文字符号化スキームです。データ交換方式、ファイル形式としては、一般的にUTF-8が使われる傾向があります。

「はしご高」を含むメールを送信したい

解決済

回答 6

投稿 編集

  • 評価
  • クリップ 4
  • VIEW 6,096

chibi_kuma

score 37

PHP5.6から、メール本文に「はしご高」や「たつ崎」などを含む
メールを送信したいと考えています。

Gmailなどからメールを送信し、ヘッダーを確認すると以下のようになっており、
UTF-8の「はしご高」や「たつ崎」を含むメールを、マルチパートメールで
送信できそうと考えました。

Content-Type: multipart/alternative; boundary=XXXX

    --XXXX
    Content-Type: text/plain; charset=UTF-8
    Content-Transfer-Encoding: base64

    メール本文

以下のサイトを参考にしながら、テストプログラムを作成してみましたが、
メール本文のみ、文字化けしてしまいます。
サーバーと、プログラム本体の文字コードは、UTF-8です。

(参考)phpメール送信例/メモ
http://qiita.com/KanaeYou/items/b096f8be1f5bbc5448fa

(参考)PHPで添付ファイル付きメールを送信
http://refirio.org/view/202

(参考)ソフトバンク メール開発ガイド(PDF)
http://creation.mb.softbank.jp/mc/tech/doc/A-089-011-Mail_ContentDevelopmentGuide_1.2.1.pdf

MIMEヘッダーや、エンコードの方式、Content-Typeや、Content-Transfer-Encodingを、
あちこちいじって、ぐちゃぐちゃ変えながら試しています。
PCメールソフト宛のみうまくいく組み合わせもあったのですが、
ソフトバンク宛に送信すると、常に文字化けです。

どこをどのように修正すべきでしょうか?
ご指導いただけたら、幸いです。

※ 参考にしたサイトが添付を送るためのコードだったので、
添付パートの部分がついていますが、実際には使用しないので、
コメントアウトになっています。

<?php
//mb_language() を使ってエンコー ディング方式を ISO-2022-JP/Base64 に設定。
//この設定は、mb_encode_mimeheader() 関数で使用されます。
mb_language("Japanese"); 

//内部文字コード指定
mb_internal_encoding("UTF-8");

// SETUP
$to[] = 'XXX@XXX.XX.XX';
$from_email= 'XXX@XXX.XX.XX';
$from_name = 'XXXXXXXX';
$subject = 'テストプログラムから送信';

$body = "これはテストです コレハテストデス 神と神 ①②③ 髙﨑黑神福 ㈱ ⅠⅡⅢ";

$attach_file = "";

// send the email
foreach( $to as $to_email ) {
    sendmail_jpn($to_email, $subject, $body, $from_email,$from_name, $attach_file);
    sleep(1);
}

echo "送信完了";



//関数-----------------------------------

function sendmail_jpn ($to, $subject, $message, $from_email,$from_name, $filepath)
{
    $mime_type = "application/octet-stream";

    // 添付ファイルのエンコード
    //$filename = basename( $filepath );

    // マルチパートのパートの区切り文字列を指定
    $boundary = '----=_Boundary_' . uniqid(rand(1000,9999) . '_') . '_';

    // 件名のエンコード
    $subject = mb_convert_encoding($subject, "ISO-2022-JP", "UTF-8");    //UTF-8 → ISO-2022-JP
    $subject = mb_encode_mimeheader_ex($subject);

    // 差出人のエンコード
    $from_name = mb_convert_encoding($from_name, "ISO-2022-JP", "UTF-8");    //UTF-8 → ISO-2022-JP
    $from_name = mb_encode_mimeheader_ex($from_name);

    // toをエンコード
    $to = "=?ISO-2022-JP?B?" . base64_encode($to) . '?= <' . $to . '>';

    // fromをエンコード
    $from = "=?ISO-2022-JP?B?" . base64_encode($from_name) . '?= <' . $from_email . '>';

    // 本文(planeパート)のエンコード
    $message = mb_convert_encoding($message, 'JIS', 'UTF-8');
    $message = "=?ISO-2022-JP?B?" . base64_encode($message) . "?=";

    //本文(htmlパート)
    $message_html = "";

    // 添付ファイルのエンコード
     //$filename = "=?ISO-2022-JP?B?" . base64_encode($filename) . "?=";


    // ヘッダーの指定
    $head = "";
    $head .= "From: {$from}\n";
    $head .= "MIME-Version: 1.0\n";
    //$head .= "Content-Type: text/plain;" . "\n";
    //$head .= "Content-Type: multipart/mixed; boundary=\"{$boundary}\"\n";
    $head .= "Content-Type: multipart/alternative; boundary=\"{$boundary}\" Content-Transfer-Encoding: base64";

    $body = "";

// text/plainパート
$body .= "--{$boundary}\n";

    // 本文
    $body .= "Content-Type: text/plain; charset=\"ISO-2022-JP\"; Content-Transfer-Encoding: \"base64\"\n";

    $body .= "\n";
    $body .= "{$message}\n";
    $body .= "\n";

// text/htmlパート
/*
$body .= "--{$boundary}\n";

    // 本文
    $body .= "Content-Type: text/html; charset=\"UTF-8\"" . "\n";
    $body .= "Content-Transfer-Encoding: \"base64\"" . "\n";
    $body .= "\n";
    $body .= "{$message_html}\n";
    $body .= "\n";
*/

// 添付ファイルパート
/*
     //$body .= "--{$boundary}\n";
     //$body .= "Content-Type: {$mime_type}; name=\"{$filename}\"\n" .
     //"Content-Transfer-Encoding: base64\n" .
     //"Content-Disposition: attachment; filename=\"{$filename}\"\n";
     //$body .= "\n";
     //
     //$fp = fopen( $filepath, "r" ) or die("Error on mailing. (attachment file cannot open)");
     //$contents = fread( $fp, filesize($filepath) );
     //fclose( $fp );
     //$f_encoded = chunk_split(base64_encode($contents)); //添付ファイルをbase64エンコードする
     //$body .= "{$f_encoded}\n";
     //$body .= "\n";
*/

//マルチパート終了
$body .= "--{$boundary}--\n";

    // メール送信
    if (mail($to, $subject, $body, $head)) {
        echo 'sendmail_jpn : OK.';
    } else {
        echo 'sendmail_jpn : FAILURE.';
    }

}

// mb_encode_mimeheader のバグ対策用
function mb_encode_mimeheader_ex ($text, $split_count = 34) {
    $position = 0;
    $encorded = '';

    while ($position < mb_strlen($text, 'ISO-2022-JP')) {
        if ($encorded != '') {
            $encorded .= "\n ";
        }

        $output_temp = mb_strimwidth($text, $position, $split_count, '', 'ISO-2022-JP');
        $position = $position + mb_strlen($output_temp, 'ISO-2022-JP');
        $encorded .= "=?ISO-2022-JP?B?" . base64_encode($output_temp) . "?=";
    }
    return $encorded;
}

文字化け時のスマホのスクショを追加します。

イメージ説明

追記

皆さん、たくさんご回答いただき、ありがとうございます。
こちらでまとめてお返事させていただく失礼をお許しください。

参考にしたサイトが「添付を付ける例」だったので、
ちょっと小難しく考えすぎたのかと思いまして、
プログラムをシンプルなものにして、再検証してみました。

<?php
mb_language("Japanese");
mb_internal_encoding("UTF-8");
$to      = 'XXX@XXXX.XXX';
$subject = 'これはテストプログラムから送信したメール!';
$message = 'これはテストです コレハテストデス 神と神 ①②③ 髙﨑黑神福 ㈱ Ⅰ Ⅱ Ⅲ';
$message = mb_convert_encoding($message, 'ISO-2022-JP-MS');
$headers = 'From: XXXX@XXXX.XXX' . "\r\n";

mb_send_mail ($to, $subject, $message, $headers);

mailではなく、mb_send_mail にしました。

ちなみに、mb_get_info()の結果は以下の通りです。

------------------------------------------------------------------------
mb_get_info()の出力結果(カゴヤ・ジャパン レンタルサーバー)
------------------------------------------------------------------------
Array
(
    [internal_encoding] => UTF-8
    [http_input] => UTF-8
    [http_output] => UTF-8
    [http_output_conv_mimetypes] => ^(text/|application/xhtml\+xml)
    [func_overload] => 0
    [func_overload_list] => no overload
    [mail_charset] => ISO-2022-JP
    [mail_header_encoding] => BASE64
    [mail_body_encoding] => 7bit
    [illegal_chars] => 0
    [encoding_translation] => On
    [language] => Japanese
    [detect_order] => Array
        (
            [0] => ASCII
            [1] => JIS
            [2] => UTF-8
            [3] => EUC-JP
            [4] => SJIS
        )
   [substitute_character] => 63
   [strict_detection] => Off
)

エンコードせずにmb_send_mailした場合

全環境で、外字が?に化けました。

ISO-2022-JP-MS にエンコードしてmb_send_mailした場合

iPhone OK
Windows LiveMail OK
AL-Mail OK
Gmail OK
Android(HUAWEI P8lite) NG
となりました。惜しい。

以下のページで紹介されていますが、
PHPで外字を含む文字列のエンコードコンバート

PHP V5.2.1以降では『iso-2022-jp-ms』というエンコーディングが追加され、
このエンコーディングでサポートされている文字も変換する事が可能になりました。
$str = mb_convert_encoding( $str, 'ISO-2022-JP-MS');
これにより、$strに(サポートされている)外字が含まれていても、正常にコンバートすることが出来ます。
但し、文字エンコードを正しくコンバート出来る事と、端末で外字を表示出来る事はイコールではありません。いくら正常にコンバートしても、表示先の端末にその外字がサポートされていなければ表示されません。

HUAWEI P8lite は、iso-2022-jp-ms を表示できないのかも知れません。
以下の添付を参照していただきたいのですが、ISO-2022-JP-MS でコンバートして送っているけど、
ヘッダーのcharsetには、ISO-2022-JP と書かれています。

イメージ説明

試しに、GmailからHUAWEI P8liteに送ってみると…

問題なく表示されました。(さすが…)

追記2

HUAWEI P8lite のみ、ヘッダー情報がメール本文内になだれ込んでいる件、
原因は、この行でした。

HUAWEI P8liteに届いたメールだけ、何故かメールの送信時間が
「1970年1月1日」になっていたので、ヘッダーが壊れてるなと…。

$headers = 'From: XXXX@XXXX.XXX' . "\r\n"; //修正前
$headers = 'From: XXXX@XXXX.XXX' . "\n";   //修正後

これでとりあえず、手持ちの端末では全てOKになりました!(ありがとうございます!)
自宅に戻らないと確認できませんが、Mac、古いガラケーなども確認したいと思います。

PHPからISO-2022-JP-MS でメールを送信されている方へ追加でお尋ね

ガラケーなど「ISO-2022-JP-MS」がサポートされていない端末も当然あるのではと
気になっています。

サーバ証明書が切り替わりますので、
「SHA-2」方式および「TLS1.0以上」に対応していない携帯端末
(2008年位より前に発売されたガラケー)は、サポート外にしようと思っていますが、
対応している機種で「ISO-2022-JP-MS」がサポートされていない機種って、
あるものなのでしょうか?(どうやって調べるんですか…こういうの…)
情報をお持ちでしたら、御知らせいただければ幸いです。

UTF-8の文字で、ISO-2022-JP-MSに含まれていない文字への対策

UTF-8の文字で、ISO-2022-JP-MSに含まれていない文字が入っていた場合にやはり化けるので、
以下の一行を追加しました。

mb_substitute_character('entity');

追記3

imutakaoruさんからいただいたコードを、実行させてみました。
無事、UTF-8のままで送れました!!
(imutakaoruさん、ありがとうございます!)

受信したメールのヘッダーを確認したところ、
となっており、Gmailに近づいた気がします。(自分の理想に近い)

MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: BASE64

UTF-8をフルカバーできるか?

ISO-2022-JP-MS に変換しないので、ISO-2022-JP-MS に含まれていない文字が本文に入っていたら
どうなるかと思い、以下のサイトで紹介されていた二字を足してみました。

マルチバイト文字を扱う際に気をつけること
(U+29E3Dの「=ホッケ」と U+50AA「=さん」)

この2字がUTF-8かどうか、よく分かりませんが、
一応、UTF-8のファイルではちゃんと書けています。

$message = 'これはテストです コレハテストデス 神と神 ①②③ 髙﨑黑神福 ㈱ Ⅰ Ⅱ Ⅲ 𩸽 傪';

これを、imutakaoruさんからいただいたコードで送信した結果は、以下の通りでした。

iPhone OK
HUAWEI P8lite 「𩸽」が文字化け
AL-Mail 𩸽 傪 とも文字化け

イメージ説明

(画像添付)

HUAWEI P8liteは フォントが省略されているのではないかと思います。

「Al-Mail」で受信したメールを外部エディタで確認してみると、
本文はちゃんとBASE64でエンコードされていました。
別のサイトで同じ文字列をBASE64エンコードして比較したところ、
合致しましたので、エンコードの問題ではなさそうです。

Gmailからも同じ文字列を、Al-Mail宛に送ってみましたが、
やっはり同じように、最後の2字が化けました。
Al-Mailの問題か、フォントの問題かなと思います。

Al-Mailは古すぎるので、もうサポート外で良いのですが、
HUAWEI P8liteは、表示して欲しかったなぁ…。

先ほど引用させていただいた、この一言に尽きるわけですね…。

文字エンコードを正しくコンバート出来る事と、
端末で外字を表示出来る事はイコールではありません。

UTF-8の全ての文字をサポートしようと思うと、
難しそうなので、(端末側のフォント事情になると、もうどうしようもない。)
サポート文字範囲は、「ISO-2022-JP-MS」に含まれている文字まで、
それ以外はエンティティするか、ゲタ文字に置き換える、という仕様の方が安心できそうです。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • ikedas

    2016/10/18 12:47

    文字化けについてのご質問では、どういうふうに見えるのかも知らせていただけるとよいです。スクリーンショットを貼り付けるのが一番です。

    キャンセル

  • zico_teratail

    2016/10/18 12:59

    具体的にどういう文字化けになったのかが記載されないと判断できない。

    キャンセル

  • chibi_kuma

    2016/10/18 13:29

    ikedasさん、zico_teratailさん、追記依頼ありがとうございました。 スクリーンショットを追加しましたので、 よろしくお願い申し上げます。

    キャンセル

回答 6

checkベストアンサー

+2

スクリーンショット追加ありがとうございます。リアルタイムで見れてないので、ほかの方と重複することも書くかもしれませんが、ともかく回答します。


「はしご高」などを送りたいのであれば、文字コードをUTF-8にしてしまうのが、プログラムを作る側にとっては簡単かと思います。しかしここでは、あえてキャラクタセットを「ISO-2022-JP」と指定しながらベンダ拡張の文字を符号化して送ることを考えます。

まず前提として、以下のコードには次の点が必須です。

  • ソースのエンコーディングはUTF-8であること。
  • ソースのエンコーディングと内部エンコーディングが一致していること。つまり、最初にmb_internal_encoding('UTF-8')が実行されていること。
  • メール送信にmb_send_mail()ではなくmail()を使うこと。今回作成するメッセージは (後述の改行コードの違いを除き) MIME準拠の完全に符号化されたメッセージになるはずなので、送信時に更なる処理は必要ないと考えられます。

以下、工夫の説明と、ご質問のコードの修正点です。

/* ご質問のコード */
    // 件名のエンコード
    $subject = mb_convert_encoding($subject, "ISO-2022-JP", "UTF-8");    //UTF-8 → ISO-2022-JP
    $subject = mb_encode_mimeheader_ex($subject);

他の方からも指摘がありますが、mb_convert_encoding()は不要です。またやはり指摘がある通り、標準のISO-2022-JPで変換すると非標準の文字は置換されてしまいます。拡張コデックを使うことにします。

/* 修正後 */
    $subject = mb_encode_mimeheader($subject, 'ISO-2022-JP-MS', 'B', "\n");

ISO-2022-JP-MSで符号化しています。私の環境では結果は「=?ISO-2022-JP?B?……?=」のようになり、望みどおりのキャラクタセット名が入りました。

また、mb_encode_mimeheader()の第4引数は、ヘッダの折り返しに使う改行コードです。既定値の"\r\n"だと、mail()などを使って送るときに正常なメッセージが送れない場合があります。ご質問のコードでは別関数を作ってほかの対策も含めて行っているようですが、改行の調整だけでよいように思います。

次にアドレスフィールド。

/* ご質問のコード */
    // 差出人のエンコード
    $from_name = mb_convert_encoding($from_name, "ISO-2022-JP", "UTF-8");    //UTF-8 → ISO-2022-JP
    $from_name = mb_encode_mimeheader_ex($from_name);

件名と同じです。ただし構造化ヘッダフィールドなので、phraseだけ符号化します。

/* 修正後 */
    // 差出人のエンコード
    $from_name = mb_encode_mimeheader($from_name, 'ISO-2022-JP-MS', 'B', "\n");

そして、ヘッダフィールドを組み立てます。

/* ご質問のコード */
    // toをエンコード
    $to = "=?ISO-2022-JP?B?" . base64_encode($to) . '?= <' . $to . '>';

    // fromをエンコード
    $from = "=?ISO-2022-JP?B?" . base64_encode($from_name) . '?= <' . $from_email . '>';

ここで$toはASCIIしか含まないので、「符号化には最小の文字集合を使う」という原則により、ISO-2022-JPなどのより大きな文字集合による符号化はしません (たとえばteratailではユーザに送られるメッセージのヘッダに「=?UTF-8?Q?ikedas?=」などというものが入っていることがありますが、これは厳密には誤りです)。

一方$from_nameは、さっき符号化したのでもう符号化してはいけません

/* 修正後 */
    $to_name = str_replace("\"", "\\\"", str_replace("\\", "\\\\", $to));
    $to = '"' . $to_name . '" <' . $to . '>';

    $from = $from_name . ' <' . $from_email . '>';

最後に本文。

/* ご質問のコード */
    // 本文(planeパート)のエンコード
    $message = mb_convert_encoding($message, 'JIS', 'UTF-8');
    $message = "=?ISO-2022-JP?B?" . base64_encode($message) . "?=";

本文 (ボディ) での符号化にはcharsetやencodingが含まれません (ボディに関しては、そういったものはContent-TypeヘッダフィールドのCharsetパラメータとContent-Transfer-Encodingヘッダフィールドで指定します)。ヘッダフィールドの符号化 (RFC 2047) とボディの符号化 (RFC 2045) は別のものです。

そもそも、ISO-2022-JPは7ビット符号で、ボディでのBASE64符号化は不要です (RFC 1468を参照)。またこの場合、転送符号化は「Content-Transfer-Encoding: 7BIT」になります。

それと、上と同様、ISO-2022-JP-MSを使わないと非標準の文字が置換されてしまいます。

/* 修正後 */
    $message = mb_convert_encoding($message, 'ISO-2022-JP-MS', 'UTF-8');

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2016/10/18 18:54

    ikedasさん、丁寧な解説ありがとうございました。
    まだ内容を100%理解は出来てないのですが、(スイマセン…勉強します!)
    取り急ぎご指摘いただいたところを修正したところ、
    マルチパートメールでも、無事送信することが出来ました。
    ありがとうございます。

    キャンセル

+2

JIS(ISO-2022-JP)にない文字の送信をしようとしているので、
そりゃ文字化けしますよね。
いっそシフトJISのまま送信してはいかがでしょうか。
「Shift_JIS」で解釈してくれるでしょうし。

(試してないので外していたらすみません)

余談ですが、
PHP: サポートされる文字エンコーディング - Manual
http://php.net/manual/ja/mbstring.supported-encodings.php
を見ていると、ケータイ3社向けのエンコーディングが用意されていたんですね、
知りませんでした。
「ISO-2022-JP-MS」「JIS-MS」なんてのもあるし。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2016/10/18 13:32

    m6uさん、ご回答ありがとうございます。
    んー、そりゃそうですよね。
    あちこち参考にしてて、ソースがごちゃごちゃになっているのですが、
    当初は、
    $message = mb_convert_encoding($message, 'JIS', 'UTF-8');
    の部分がなく状態でやっていたのですが、
    やはりダメなんですよね。
    スクリーンショットを追加しました。
    Bの方では、JISにせずにやってみたのですが…

    キャンセル

  • 2016/10/18 13:37

    UTF-8にもせず、Shift_JISでいかがでしょうか。
    また、メッセージ本文はすでにContent-Typeにてエンコードを指定しているため、
    Base64エンコードしたそのママを使えば良さそうな気がします。

    キャンセル

  • 2016/10/20 10:53

    m6uさん、ご指導いただき、ありがとうございました。
    今回はShift-JISからUTF-8に文字コードを変更するのが改修目的だったもので、
    UTF-8で送ることにこだわっておりました。
    結果的に、UTF-8をBASE64エンコードしたものを送信できることが確認できました。
    どうもありがとうございました。
    またご指導お願い申し上げます。

    キャンセル

+2

うーん、個人的には過去「mb_send_mail」でメール送信したら、わざわざ本文などをmb_convert_encodingを使って変換せずとも自動的にISO-2022に変換されてましたよ(PHPのコード自体はUTF-8)。

メール送信をmailではなくmb_send_mailにして、なおかつmb_convert_encodingを使わないようにしたらどうなるかやってみてください。(※ただしContent-Type等の必要なヘッダーは指定してください)

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2016/10/18 13:49

    試しにローカルPCのThunderbirdからGmail宛に該当の本文をメール送信したところ、文字化けせずに送れました。すなわち、ISO-2022でも送れる文字たちであるはず。

    ヘッダー(抜粋)は
    MIME-Version: 1.0
    Content-Type: text/plain; charset=iso-2022-jp; format=flowed; delsp=yes
    Content-Transfer-Encoding: 7bit
    となってました。

    キャンセル

  • 2016/10/18 15:52

    >ヘッダーのcharsetには、ISO-2022-JP と書かれています。

    それならヘッダーにMS付きを明示してみたら?

    $headers = "";
    $headers .= "Content-Type: text/plain; charset=ISO-2022-JP-MS\n";
    $headers .= "Content-Transfer-Encoding: 7bit\n";
    $headers .= "From: test <XXXX@XXXX.XXX>\n";

    キャンセル

  • 2016/10/20 11:00

    zico_teratailさん、ご指導ありがとうございました。
    mb_send_mailが、ただメールを送るのではなく、エンコードも担当していたとは知らず、えらく遠回りをしてしまいましたが、お陰様で、目的には達することが出来ました。
    ちゃんと関数マニュアルを読みこまないとダメですね…。
    ありがとうございました。またご指導よろしくお願い申し上げます。

    キャンセル

+2

Content-Typeのcharsetは'ISO-2022-JP'のままで
本文(mail body)のエンコード形式指定で'ISO-2022-JP-MS'と指定してください。

うちでは平文メールで「たち埼」「はしご高」送信できています。
メール送信はPear::Mailを使用しSMTP送信しています。
$bodyISO2022JPMS = mb_convert_encoding($body, "ISO-2022-JP-MS", "UTF-8");

追記:
Mail headerの charsetが「ISO-2022-JP」なのはこれで正解です。
P8liteのメールアプリでは本文にメールヘッダーがなだれ込んでますね。アプリのバグのような気がしますが。。。
P8liteでGmailアプリをインストールし受信してみると正常に表示されないでしょうか?

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2016/10/20 11:05

    Y.H. さん、ご指導いただき、ありがとうございました。
    お陰様で、ISO-2022-JP-MSで、はしご高やたち崎を送信することが出来ました。
    P8liteで本文にメールヘッダーがなだれ込んでいた件もご指摘いただいたお陰で、
    メールのタイムスタンプが1970年1月1日になっている原因と気がつく事ができました。
    ISO-2022-JP-MSで送信していても メールヘッダーの charsetは「ISO-2022-JP」になるという情報は大変参考になりました。
    これを知らないと「あれ、おかしい!」と、また右往左往するところでした。
    ありがとうございました。またご指導よろしくお願い申し上げます。

    キャンセル

+1

m6uさんのおっしゃる通りSHIFT_JISかいっそUTF-8で送ればいいと思います。

どこで化けているのか一応検証してみました。

<?php
        mb_language("Japanese");
        mb_internal_encoding("Shift_JIS");

        $body = 'これはテストです コレハテストデス 神と神 ①②③ 髙﨑黑神福 ㈱ ⅠⅡⅢ';
        $body_ISO2022 = mb_convert_encoding($body, 'ISO-2022-JP', 'AUTO');

        var_dump($body_ISO2022);
?>


とすると、思った通りmb_convert_encoding()から戻ってきた時点で
string(60) "これはテストです ????????? 神と? ??? ????? ? ???"
と、ISO-2022-JPに無い字は全部?に変換されちゃうので、そっから先には行きませんね。

追記

以下のソースにてお試しいただけますでしょうか。

<?php
mb_language("uni");                        // mb_send_mailにて送る際のコードをUTF-8にする("Japanese"だとISO-2022-JPになるので)
mb_internal_encoding("UTF-8");
$to      = 'XXX@XXXX.XXX';
$subject = 'これはテストプログラムから送信したメール!';
$message = 'これはテストです コレハテストデス 神と神 ①②③ 髙﨑黑神福 ㈱ Ⅰ Ⅱ Ⅲ';
// $message = mb_convert_encoding($message, 'ISO-2022-JP-MS'); // encodingの変更をせずutf-8で送る
$headers = 'From: XXXX@XXXX.XXX' . "\r\n";

mb_send_mail ($to, $subject, $message, $headers);

?>

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2016/10/18 19:45

    imutakaoruさん、情報ありがとうございます。
    結果は、追記3に記載させていただきましたので、そちらをご覧いただけますでしょうか?

    キャンセル

  • 2016/10/19 09:44

    おおむね解決に近づいたようでなによりです。
    あとはどのへんを妥協点にするか、くらいですね。

    キャンセル

  • 2016/10/20 10:57

    imutakaoruさん、ご指導いただき、ありがとうございました。
    お陰様で、UTF-8でBASE64エンコードしたものを送ることが出来ました。
    今回のエンコードしたものが正しく送信できていても、
    それが正しく表示されるとは限らないという点も、今回の大きな収穫でした。
    おっしゃる通り、妥協点・落とし所をお客様と決めて、
    先に進めたいと思います。
    ありがとうございました。またご指導よろしくお願い申し上げます。

    キャンセル

+1

こちらの記事、参考になりそうなので、貼っておきます。
もう見ていたら、ごめんなさい。
ISO-2022-JPで『髙』を送信
【php】はしご高が文字化けしない文字コード変換

ちなみに、UTF-8 から Shift-JIS にすると、全角「-」や全角「~」、丸付きの数字(①など)、ローマ数字(Ⅲなど)などが文字化けを起こす可能性があるかと。
(別件でですが、この間引っかかった問題なもので^^;)

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2016/10/20 11:08

    kaputarosさん、参考情報ありがとうございました。
    別件ですが、UTF-8からShift-JISに変換するプログラムも作成する予定なので、
    お知らせいただいた情報は大変参考になりました。
    ありがとうございました。またご指導よろしくお願い申し上げます。

    キャンセル

  • 2016/10/21 10:36

    お役に立ててよかったです^^
    文字コードの問題はきっと、ずっとぶち当たる壁ですよね。
    最近Mac/Windows間のファイル受け渡し等が普通になってきてるので、更に拍車が・・・

    自分もまだまだ勉強不足です。がんばりましょ~♪

    キャンセル

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

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

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

  • PHP

    24602questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

  • メール

    318questions

    メールは、コンピュータネットワークを利用し、 情報等を交換する手段のことです。

  • UTF-8

    129questions

    UTF-8は8ビット符号単位の文字符号化形式及び文字符号化スキームです。データ交換方式、ファイル形式としては、一般的にUTF-8が使われる傾向があります。