モイ!
こんにちは、ロニーです。
今回は技術ブログです。
我が家のコニーさんは登場しません!
ごめんなさいね♡
さて、今PHPでメールフォームを作っているのですが、
inputタグのtypeをhiddenにし、
PHPファイルにPOSTした値をメール本文に載せるときに、うまくいかずハマりました。
メールフォームにおけるお問い合わせ本文って、複数行書くこと、当然ありますよね。
それをtextareaタイプで送れば、受け取ったときにも改行は問題なく適用されます。
しかしhiddenタイプで送ると、これはうまくいかない。
改行を含む複数行のテキストが入った変数をそのままhiddenのvalueとして渡すと、
なぜか2行目以降が消されてしまうんです。
送る側でこうして
// inquery_check.php
$text = "1行目
2行目
3行目"
こう受け取ると
// mail_send.php
$received_text = $_POST["text"];
echo $received_text
出力結果はこうなる
1行目 // 2行目以降が欠落
これはどうやらHTTPの仕様上、改行コードは特別な意味を持つためで、
こういったエラーが出るみたいなんです。
これを解消するためには、
valueとして渡す前に一度改行コードをエスケープしてあげてからPOSTし、
受け取った後にアンエスケープしてあげる必要があります。
今回僕はエスケープとアンエスケープをそれぞれ関数にしました。
理由はメール送信プログラムがごちゃっとして可読性が下がるのを避けるため。
そこまでシビアな処理時間を求められないですしね。
(正直使い回さないので関数化する必要は特になし。)
// 改行コードをエスケープする関数
function escape_nl($str)
{
// 改行コードはCRLFに統一
$new_str = str_replace(["\r\n", "\r", "\n"], "\\r\\n", $str);
return $new_str;
}
// エスケープされた改行コードをアンエスケープする関数
function unescape_nl($str)
{
// 改行コードはCRLFに統一
$new_str = str_replace("\\r\\n", "\r\n", $str);
return $new_str;
}
送る側でエスケープして
<?php
$text = "1行目
2行目
3行目"
?>
<input type="hidden" name="text" value=<?= escape_nl($text) ?> >
受け取る側でアンエスケープ。
$received_text = $_POST["text"};
$received_text = unescape_nl($received_text);
echo $received_text
出力結果はこうなる。
1行目
2行目
3行目
なぜわざわざhiddenタイプで複数行のテキストを送ってるのかって話ですが、
これには深いわけがあってですね。
メールフォームを、
1.入力フォームを定義したindex.html、
2.確認画面のinquery_check.php、
3.メール送信処理と完了画面への遷移を行うmail_send.php
のように分けるとすると、
確認画面で「メールを送信する」ボタンを押した瞬間に、
フォーム入力された$_POST情報が消えてしまい、
送信したメール内容に情報が載らなくなるためです。
メールを送信するボタンを含むformタグ内に、
hiddenタイプで各フォーム情報を再度POSTしてあげることで、
mail_send.phpにデータが渡るという仕組みです。
まぁ、
SESSION使えばこんなことしなくてもデータ渡る気がしますが、
諸事情あって今回はSESSIONを使わずにデータを2ページ先まで送る必要があったためこうなりました。
補足ですが、
POST変数を受け取った際にnl2br関数で改行タグ(<br>)に戻す必要があるかなと思ったのですが、これは間違いでした。
正しくは、アンエスケープ!
「//r//n」 → 「/r/n」
です。
nl2br関数を挟むと、<br>が文字列として表示されてしまいます。
コメント