現在、メールフォームの文字コードについて勉強しております。
入力、確認、送信と画面を遷移するメールフォームを作成しました。
送信画面のコードを末尾に記載致します。
mb_language('ja')
を指定しております。
ja
または Japanese
の場合は、ISO-2022-JP/Base64
でエンコードされます。
ISO-2022-JP
は、丸囲み文字の ①②㈱髙
や アイウエオ
などの半角カナには対応しておりません。
そのため、mb_convert_encoding
を使って ISO-2022-JP-MS
に文字エンコーディングを変換しています。
作成したメールフォームから ①②㈱髙アイウエオ
を入力して送信したら、問題なく表示されました。
Windows7 の環境で WindowsLive Mail 2012 と Thunderbird 45.8.0 のメーラーで問題なく表示されました。
受信したメールのソースを確認しましたが、Content-Type: text/plain; charset=ISO-2022-JP
としか記載なく ISO-2022-JP-MS
の表記がありません。
なぜ、メール本文の ①②㈱髙アイウエオ
は正しく表示されるのでしょうか?
ご存じの方いれば、教えてください((_ _ (´ω` )ペコ
入力画面
php
1<?php 2// 他のサイトでインラインフレーム表示を禁止する(クリックジャッキング対策) 3header('X-FRAME-OPTIONS: SAMEORIGIN'); 4?> 5<!DOCTYPE html> 6<html lang="ja"> 7<head> 8<meta charset="UTF-8"> 9<title>入力画面</title> 10</head> 11<body> 12 13<h1>お問い合わせ(入力画面)</h1> 14 15<form method="post" action="confirm.php"> 16<table> 17 <tr> 18 <th>お名前(必須)</th> 19 <td><input type="text" name="name"></td> 20 </tr> 21 <tr> 22 <th>ふりがな(必須)</th> 23 <td><input type="text" name="ruby"></td> 24 </tr> 25 <tr> 26 <th>メールアドレス(必須)</th> 27 <td><input type="text" name="mail"></td> 28 </tr> 29 <tr> 30 <th>内容(必須)</th> 31 <td><textarea name="content"></textarea></td> 32 </tr> 33</table> 34<button>送信内容確認</button> 35</form> 36 37</body> 38</html>
確認画面
php
1<?php 2// 他のサイトでインラインフレーム表示を禁止する(クリックジャッキング対策) 3header('X-FRAME-OPTIONS: SAMEORIGIN'); 4 5// IEで発生するコンテンツタイプSniffing対策 6header('X-Content-Type-Options: nosniff'); 7 8// XSSフィルタの設定 9header('X-XSS-Protection:1; mode=block'); 10 11// HttpOnly属性 の指定 12ini_set('session.cookie_httponly', 1); 13 14// セッション開始 15session_start(); 16 17// HTML特殊文字をエスケープする関数 18function h($str) { 19 return htmlspecialchars($str,ENT_QUOTES,'UTF-8'); 20} 21 22/* -------------------------------------------------- 23 トークンの作成(CSRF対策) 24 25 ※使用しているPHPのバージョン・環境にあわせて 26 トークンを選んでね。不要なトークは削除してね。 27-------------------------------------------------- */ 28 29// PHP 7.0 以降 30//if(!isset($_SESSION['token'])) { 31// $_SESSION['token'] = bin2hex(random_bytes(32)); 32//} 33 34// PHP 5.3 ~ 5.x ※OPENSSL導入済 35if(!isset($_SESSION['token'])) { 36 $_SESSION['token'] = bin2hex(openssl_random_pseudo_bytes(32)); 37} 38 39// PHP 5.3 未満 40//if(!isset($_SESSION['token'])) { 41// $_SESSION['token'] = hash('sha256', session_id()); 42//} 43 44// トークンを代入 45$token = $_SESSION['token']; 46 47?> 48<!DOCTYPE html> 49<html lang="ja"> 50<head> 51<meta charset="UTF-8"> 52<title>確認画面</title> 53</head> 54<body> 55 56<h1>お問い合わせ(確認画面)</h1> 57 58<?php 59 60// POSTされたデータを変数に代入(magic_quotes_gpc = On + NULLバイト 対策) 61foreach (array('name','ruby','mail','content') as $v) { 62 $$v = filter_input(INPUT_POST, $v, FILTER_DEFAULT, FILTER_FLAG_STRIP_LOW); 63} 64 65$error_flag = 0; 66 67// 必須項目は未入力をチェック 68if ($name === '' || $name === NULL) { 69 echo '<p>お名前をご入力してください。</p>'; 70 $error_flag = 1; 71} elseif (mb_strlen($name) > 50) { 72 echo '<p>お名前は 50 文字以内で入力してください。</p>'; 73 $error_flag = 1; 74} 75 76if ($ruby === '' || $ruby === NULL) { 77 echo '<p>ふりがなをご入力してください。</p>'; 78 $error_flag = 1; 79} elseif (mb_strlen($ruby) > 50) { 80 echo '<p>ふりがなは 50 文字以内で入力してください。</p>'; 81 $error_flag = 1; 82} 83 84if ($mail === '' || $mail === NULL) { 85 echo '<p>メールアドレスをご入力してください。</p>'; 86 $error_flag = 1; 87} elseif (mb_strlen($mail) > 100) { 88 echo '<p>メールアドレスは 100 文字以内で入力してください。</p>'; 89 $error_flag = 1; 90} elseif (!filter_var($mail, FILTER_VALIDATE_EMAIL)) { 91 echo '<p>メールアドレスの形式が正しくありません。</p>'; 92 $error_flag = 1; 93} 94 95if ($content === '' || $content === NULL) { 96 echo '<p>内容をご入力してください。</p>'; 97 $error_flag = 1; 98} elseif (mb_strlen($content) > 500) { 99 echo '<p>内容は 500 文字以内で入力してください。</p>'; 100 $error_flag = 1; 101} 102 103// エラーがある場合は、戻るボタンを表示し、エラーがない場合は、確認画面を表示 104if ($error_flag === 1) { 105 echo '<button onClick="history.back(); return false;">戻る</button>'; 106} else { 107 // セッション変数に代入 108 $_SESSION['name'] = $name; 109 $_SESSION['ruby'] = $ruby; 110 $_SESSION['mail'] = $mail; 111 $_SESSION['content'] = $content; 112 113 // 確認用画面の表示 114 ?> 115 116 <form method="post" action="send.php"> 117 <table> 118 <tr> 119 <th>お名前</th> 120 <td><?php echo h($name); ?></td> 121 </tr> 122 <tr> 123 <th>ふりがな</th> 124 <td><?php echo h($ruby); ?></td> 125 </tr> 126 <tr> 127 <th>メールアドレス</th> 128 <td><?php echo h($mail); ?></td> 129 </tr> 130 <tr> 131 <th>内容</th> 132 <td><?php echo nl2br(h($content)); ?></td> 133 </tr> 134 </table> 135 <input type="hidden" name="token" value="<?php echo h($token); ?>"> 136 <button>送信</button> 137 </form> 138 139 <?php 140} 141 142?> 143 144 145</body> 146</html>
送信画面
php
1<?php 2// 他のサイトでインラインフレーム表示を禁止する(クリックジャッキング対策) 3header('X-FRAME-OPTIONS: SAMEORIGIN'); 4 5// IEで発生するコンテンツタイプSniffing対策 6header('X-Content-Type-Options: nosniff'); 7 8// XSSフィルタの設定 9header('X-XSS-Protection:1; mode=block'); 10 11// HttpOnly属性 の指定 12ini_set('session.cookie_httponly', 1); 13 14// セッション開始 15session_start(); 16 17// mb_send_mail のエンコーディング 18mb_language('ja'); 19 20// 内部文字エンコーディングを設定 21mb_internal_encoding('UTF-8'); 22?> 23<!DOCTYPE html> 24<html lang="ja"> 25<head> 26<meta charset="UTF-8"> 27<title>送信画面</title> 28</head> 29<body> 30 31<h1>お問い合わせ(送信画面)</h1> 32 33<?php 34 35// token セッション変数がセットされ、NULLまたは空文字 36if(isset($_SESSION['token']) && !empty($_SESSION['token'])) { 37 38 // POST['token']の値をtoken変数に代入 39 $token = filter_input(INPUT_POST, 'token', FILTER_DEFAULT, FILTER_FLAG_STRIP_LOW); 40 41 // 各セッション変数を各変数に代入 42 $name = isset($_SESSION['name']) && is_string($_SESSION['name']) ? mb_convert_encoding($_SESSION['name'], 'ISO-2022-JP-MS', 'ASCII,JIS,UTF-8,eucJP-win,SJIS-win') : ''; 43 $ruby = isset($_SESSION['ruby']) && is_string($_SESSION['ruby']) ? mb_convert_encoding($_SESSION['ruby'], 'ISO-2022-JP-MS', 'ASCII,JIS,UTF-8,eucJP-win,SJIS-win') : ''; 44 $mail = isset($_SESSION['mail']) && is_string($_SESSION['mail']) ? mb_convert_encoding($_SESSION['mail'], 'ISO-2022-JP-MS', 'ASCII,JIS,UTF-8,eucJP-win,SJIS-win') : ''; 45 $content = isset($_SESSION['content']) && is_string($_SESSION['content']) ? mb_convert_encoding($_SESSION['content'], 'ISO-2022-JP-MS', 'ASCII,JIS,UTF-8,eucJP-win,SJIS-win') : ''; 46 47 // トークンの値が一致しない場合は、エラー文を表示し、一致する場合は送信する 48 if($token !== $_SESSION['token']) { 49 50 echo '<p>送信後に再度アクセスされたか、お問い合わせの手順に誤りがあります。<br>お手数ですが、最初の画面からご入力ください。<p>'; 51 52 } else { 53 54 /* 運営側へ送信するメールの設定 */ 55 56 // 送信先のメールアドレス 57 $to = '□□□□□@□□□□□□□'; 58 // 件名 59 $subject = 'お問い合わせからの送信'; 60 // 本文 61 $message = "◆お名前\n$name\n\n◆フリガナ\n$ruby\n\n◆メールアドレス\n$mail\n\n◆内容\n$content"; 62 // オプション 63 $option = '-f'. $to; 64 65 66 /* 問い合わせされた方へ自動返信するメールの設定 */ 67 68 // 件名 69 $auto_subject = 'お問い合わせを承りました'; 70 // 送信元のメールアドレス 71 $auto_from = 'From:' . $to; 72 // 本文 73 $auto_message = 74"※このメールは自動返信によるものです。 75 76$name 様 77 78このたびは、お問合せいただき、誠にありがとうございました。 79 80お送りいただきました内容を確認の上、担当者より折り返しご連絡させていただきます。 81"; 82 83 /* セーフモードがONの場合は、mb_send_mailの第5引数が使えないため、処理を分岐して送信 */ 84 if(ini_get('safe_mode')) { 85 86 /* 運営側と自動返信のメールの送信が完了したら、送信完了の文章を表示する */ 87 if(mb_send_mail($to, $subject, $message, "From:$mail") && mb_send_mail($mail, $auto_subject, $auto_message, $auto_from)) { 88 echo '<p>このたびは、お問合せいただき、誠にありがとうございました。<br>お送りいただきました内容を確認の上、担当者より折り返しご連絡させていただきます。</p>'; 89 } else { 90 echo '<p>大変申し訳ございませんが、メールの送信に失敗しました。<br>お手数ですが最初からやり直してください。</p>'; 91 } 92 93 } else { 94 95 /* 運営側と自動返信のメールの送信が完了したら、送信完了の文章を表示する */ 96 if(mb_send_mail($to, $subject, $message, "From:$mail", $option) && mb_send_mail($mail, $auto_subject, $auto_message, $auto_from, $option)) { 97 echo '<p>このたびは、お問合せいただき、誠にありがとうございました。<br>お送りいただきました内容を確認の上、担当者より折り返しご連絡させていただきます。</p>'; 98 } else { 99 echo '<p>大変申し訳ございませんが、メールの送信に失敗しました。<br>お手数ですが最初からやり直してください。</p>'; 100 } 101 102 } 103 104 } 105 106 // セッションの破棄 107 $_SESSION = array(); 108 session_destroy(); 109 110} else { 111 echo '<p>送信後に再度アクセスされたか、お問い合わせの手順に誤りがあります。<br>お手数ですが、最初の画面からご入力ください。</p>'; 112} 113 114?> 115 116</body> 117</html>

回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/05/02 09:01