メールフォーム作成に関する忘備録

忘備録
https://appdev-room.com/php-questionform3#google_vignette
のサイトを見ながらメールフォーム実装

phpは動きが難しい…、ナニコレってコードもある。
・form.php

html部分

form部分のひな型は割愛するが、まず

method="post" action="form.php"が大切。

method="post"
"やあサーバー、このデータを見て適切な結果を返してよ。”
参考:https://developer.mozilla.org/ja/docs/Learn/Forms/Sending_and_retrieving_form_data

メールフォームは入力されたデータに基づいて結果を返す為"post"
が適切なように思う。

action="form.php"
メールフォームをクリックすると、action="〇○"〇○の所にリンクみたいに飛ぶ(データを渡す)と
考えていたが、同じファイルにループしてるじゃないか。

if (isset($_POST['submit']))
これはこのファイル内で「送信ボタン」のクリックをトリガーにphpで
入力されたデータに対してチェックし、その後

header('Location:http://localhost/Questionform/confirm.php');
このヘッダーにてconfirm.phpに飛ぶことを示している。

要するに「送信クリック→飛ぶ」ように見た目見えるが
「送信クリック→データチェック→飛ぶ」という「データチェック」の部分を

「送信ボタン」のクリックをトリガーにして作っているのがまず驚きだった。

「データチェック」においては、
入力された(postされた)データを扱うべく変数に入れるのだが、ここでも
エスケープ処理という加工を施してから入れている。
(野菜の出荷前に泥を落とすような感じだろうか…)

htmlspecialchars($_POST['kinds'], ENT_QUOTES | ENT_HTML5);
参考:https://www.php.net/manual/ja/function.htmlspecialchars.php

htmlspecialchars:特殊文字を HTML エンティティに変換
htmlのただの文字列に変えるまじないと解釈
(エンティティ‥‥ポケモンのエンテイの進化系か何かか?)

ENT_QUOTES | ENT_HTML5
シングルクオートとダブルクオートを共に変換しつつHTML 5 として処理

まずこのエスケープ処理をしてようやく変数に梱包される。

if (trim($name) === '' || trim($name) === " ")が出てくる。
これは結論「空白」を文字として認識してないかのチェックである。
trim($name)により変数$name内の名前に含まれている「空白」をトリム(除く)
ことで「ちゃんと文字が入ってるか」をチェックしている

(箱を開けたら中は空気のみ入ってたパターンを除くイメージ)

そしてエラーが無ければ
$_SESSION['kinds'] = $kinds;
$_SESSION[キー名] = 値;
これがまた、よくわからなかった。えええ変数を何に入れているの?って感じだ。
参考:https://www.sejuku.net/blog/25276

$_SESSION
PHPにおいてセッション情報を保持するための変数

うーん。コンフリクトとか引数を別のファイルに渡すとかをイメージしては
どうかと考えた。多分変数に値を保持するだけでは「他のファイルに渡せる形」では
ないのかもしれない。

(野菜でいうと、綺麗に洗って状態のままでは保存が効かないから、冷凍してから
遠くの地域に出荷するイメージだろうか。)

confirm.php

if (isset($_SESSION['kinds'])) {
 $kinds = $_SESSION['kinds'];
$name = $_SESSION['name'];

ここで思った事。if (isset($_SESSION['name']))
でもいいんじゃないか?
ただ、これは深堀ってもなーって気がするから一旦おいておく。

これは冷凍した野菜が届いたかどうかをチェックして
そこで使えるように解凍してるイメージだろうか。

(正直、なんで繰り返してんだろうと思ったからだ)

<h2>お問い合わせ内容確認</h2>~
th>お問い合わせ種別</th>
<td><?php echo $kinds; ?></td>
ここは分かりやすい。この部分については
「php出来るよ」とふんぞり返れるくらいには分かりやすい。

// ここにトークンを生成するコードを記述
$token = sha1(uniqid(mt_rand(), true));
$_SESSION['token'] = $token;

トークンを作って、トークンを冷凍してるイメージだろうか
ふんぞり返ったまま倒れてしまいたいくらいに見たことない。

参考:https://pentan.info/php/sample/uniq_id.html
とりあえず一意なキーを生成するらしい。
sha1()ハッシュ変換:半角英数字のみにする

uniqid(mt_rand(), true)
mt_rand():乱数を用いる
true:ドット『 . 』と数字9文字が追加され、文字数が23文字になる。

つまり…半角英数字の乱数を用いて23文字くらいの数字の文字列を生成する。
では$_SESSION['token'] にはランダムな数字の文字列が入ってるって事かもしれない。

<!-- POSTの送信先はsend.phpであることに注意してください -->
<form method="post" action="send.php">
  <input type="hidden" name="token" value="<?php echo $token ?>">
  <button type="submit" value="送信">送信</button>
  <a href="form.php?action=edit">戻る</a>

見た瞬間思ったよ。「うわ、濃い」ってね。ひとまず分解してみたいと思う。
テリヤキバーガーをバンズとパテに分けるかの如く。(そしてパテだけ親戚に
食べられるという悲劇…この話は脱線しそうだからいいか…)

<form method="post" action="send.php">
<button type="submit" value="送信">送信</button>

send.phpへこのファイルの情報を送る。そらそうだろとは思うけど、
ここで
<input type="hidden" name="token" value="<?php echo $token ?>">
ここが良く分からず、とりあえず「書く」になっていたんだ。

恐らくvalue="<?php echo $token ?>は$tokenというランダムな数字の列が
入ってるはず

それをinput type="hidden"でこっそり送信する為に追加していると思う。
send.phpのアドレスを決め打ちで入力してのアクセスを防ぐ。

おそらく$tokenは決め打ちでは同じものが入力されない…という事だろうか。

$_SESSION['token'] = $token;
セッションによるトークン

<input type="hidden" name="token" value="<?php echo $token ?>">
インプット、method=post によるトークン

この中身は同じだけど、区別されるトークンをsend.phpへ渡している。
うーん。鍵と錠を作って渡すような感じだろうか…

<a href="form.php?action=edit">戻る</a>
これは確認画面からform.phpに戻る為のコード

?action=editは$_GET['action']にeditを格納する為に必要。
これはform.phpに戻った際に「すでに入力した部分を保持」する目的を達成する為
に必要らしい。

ここでform.phpにもどってみてみる。
if (isset($_GET) && isset($_GET['action']) && $_GET['action'] === 'edit')

&&こういうのが複数あるとある種漢文のような読み解き方のコツがいるんじゃないかと
思う事がある。

&&:かつ
isset($_GET):$_GETに変数がセットされているか
isset($_GET['action']) :$_GET['action']に変数がセットされているか
$_GET['action'] === 'edit':セットされている変数の値は'edit'か

つまり、$_GETに変数がセットされており、かつそれは($_GET['action']かつ中身が'edit'
と言えそう。

isset($_GET['action']) && $_GET['action'] === 'edit'
ここだけで良くない?と思うが違うのか

この条件はsend.phpからform.phpへ戻った時に満たされる。ある種のトークンのように思える。
イメージとしてはスタンプラリー

$name = $_SESSION['name'];
この部分で選択して冷凍保存したデータがロードされるイメージ

その後のhtml文の変更ではわかる部分とわかりにくい部分があった。
①<?php if(isset($kinds)&&$kinds==="依頼"){echo "checked";}?>
②value=<?php if(isset($title)){echo $title;} ?>

上記は分かる。
①はラジオボタンにおいて、選択したものの中身を照合し、「選択した箇所がチェックされている状態にする」
②はinput等において記入されている(変数に中身がある)部分についてはその中身を表示させる。

<?php if(isset($kinds)&&$kinds==="質問"){echo "checked";}else{echo "checked";}?> >
これがよくわからなかった。①に似てるけど…elseにしてもチェックしてるしどゆこと?

あと不明点。

メール、確認メールはどう表示したらいいのか
(中身同じだし、javascriptで同じ内容かチェックして、phpではメールだけチェックして
両方に同じものが入るようにした)

個人情報確認とかの1つのチェックボックスはどうしたらいいの
javascriptでチェックして、phpでは省いた

send.php
if($_SESSION['token'] === $_POST['token'])
少し戻るが、さっき言ってたセッションとしてのトークンとポストとしてのトークンを
チェックする。

合ってたらメール送信、間違ってたらform.phpに戻る事をしている

if(isset($_SESSION['kinds'])){
 $name = $_SESSION['name'];
$email = str_replace(array("\r","\n"),'',$_SESSION['email']);

これで冷凍したデータを解凍しているような動きはすでにみたが、見覚えない部分がある。
str_replace(array("\r","\n"),'',$_SESSION['email'])
参考:https://appdev-room.com/securty

メールヘッダインジェクション対策としてこうなってるらしい。
これをしないと、意図しない人にも送信される
str_replace関数

$to = "自分のメールアドレス"; ⇦ここは置き換えてください。
$mailtitle = "{$name}様よりお問い合わせが届きました。";
$contents = <<<EOD

$mailtitle = "{$name}様
ここで躓いた事。「苗字と名前」を分けてる場合、どうしたらいい?

{$F_name}{$L_name}様
とかってするんだろうか。してみたけどどうもエラーっぽかったような

$contents = <<<EOD

EOD;
ここ辺りから理解があやふやになってくるんだが、EOD間の中身を$contents
に入れるイメージかな。

$from = 'From: '.$email ;
From:xxxx@xxxx みたいな感じ

$from2 = "Return-Path:" . $to . "\r\n";
$from2 = $from2 . 'From: ' . $to;
ここは良く分からない。

最初の1文目でReturn-Path:メアド 改行 とか?

2文目で Return-Path:メアド 改行
     From:メアド とか?

mb_send_mail関数

$param = "-f" . $to;
ここが何を示してるのかよくわからなかった。

$_COOKIE
参考:https://qiita.com/Yuki-Kurita/items/ba32024d75c682945a03

この記事が気に入ったらサポートをしてみませんか?