Edited at

PHPでメールフォームを作る


環境


  • Debian9

  • PHP7

  • nginx/1.14.0

  • exim4.91

webページはすでに公開している。PHPも動く。

mailコマンドでeximからgmailにメール送信できている。


HTML

下記の<form>を書く


mail.html

<form name="contact" method="POST" action="mail.php">

<p>
<label> 名前:<br> <input type="text" name="name" id="input_name"/></label>
</p>

<p>
<label> メールアドレス:<br> <input type="email" name="email"id="input_mail"></label>
</p>

<p>
<label> 件名:<br> <input type="text" name="subject" id="input_subject"></label>
</p>

<p>
<label> 問い合わせ内容:<br> <textarea name="message" id="text_content"></textarea></label>
</p>

<p>
<button type="submit">送信</button>
</p>



PHP


mail.php

<?php

$message = "name: " . $_POST["name"] . "\nsubject: " . $_POST["subject"] . "\nfrom: " . $_POST["email"] . "\nbody: \n" . $_POST["message"];
if (!mb_send_mail("test@gmail.com", $_POST["subject"], $message)) {
exit("error");
}

?>


ブラウザでmail.htmlにアクセスして、gmailに送信されるか確認する


注意


  • PHPのmail()およびmb_send_mail()は第4引数以降に追加パラメータを設定できるが、これらは適切にエスケープしないと不正なコマンドをsendmail(mail)コマンドに渡される危険性があるらしい。そのため今回は第4以降を使用しなかった。


(2019/02/21追記)エスケープする

How to sanitze user input in PHP before mailing?にある回答よるとメールのタイトルに改行コードが入るのを許すと任意のメールヘッダを追加される恐れがある。これを防ぐために$_POST["subject"]をエスケープして使う。


mail.php

<?php

$message = "name: " . $_POST["name"] . "\nsubject: " . $_POST["subject"] . "\nfrom: " . $_POST["email"] . "\nbody: \n" . $_POST["message"];
$safe_subject = str_replace(array("\r","\n"),array(" "," "), $_POST["subject"]);
if (!mb_send_mail("test@gmail.com", $safe_subject , $message)) {
exit("error");
}
?>

以下、エスケープについてのメモ


  • メール本文はエスケープする必要はない。

  • 宛先メールアドレスをユーザに入力させるときはfilter_var()を使う。

filter_var($_POST['email'], FILTER_SANITIZE_EMAIL);



  • htmlspecialchars()はHTMLに出力するときのエスケープであり、メール(やサーバ上でのコマンド実行)には関係ない。

この節の参考文献:


参考

PHPでメールフォームから宛先(Gmail)へ送信できない

Why mail() is dangerous in PHP

mb_send_mail(),mail()で第5引数を設定する際の注意点