PHPでお問い合わせフォームを作る　その４　セッションを使ってみる

#はじめに
これまで３回に渡ってPHPを使った「お問い合わせフォームを作る」を投稿してきました。
[その１](https://qiita.com/hotate_chan/items/b8ac6b270eac50b0b8e2)　[その２](https://qiita.com/hotate_chan/items/dc95f9880f6a1dfa3490)　[その３](https://qiita.com/hotate_chan/items/64c3a50b1eb490ccfc71)
その中で色々な方々に「こうした方がいい」というコメントをありがたく頂きました。
その中でもテンプレート読み込みは htmlファイルは`require`の方がいい、というコメントを活用させて、今までの造りとは違う形でこの**その４**を書こうと思います(テンプレートの読みは文字列読み込みではなくファイル読み込みに変更します~~朝令暮改~~)。

やりたい事は、データの受け渡しにおいて**セッション**を使う事です。
それでは始めましょう。

##セッション？？
そもそもセッションて何？
ざっくりと絵で説明します。ざっくりとです。
###データの送信
![cookie1](https://p79.tr0.n0.cdn.getcloudapp.com/items/YEud0Qrd/ooo.png?v=0224a0a2aa63166a6867995f70c908ff)

ざっくりすぎますが、ブラウザ側(クライアント側)から**今からデータ投げま〜す**とリクエストが投げられます。
それを受け取ったサーバはデータを保存し、保存先を特定する一意のID(session id)をブラウザに送り返します。


###データの受け取り
ブラウザ側でデータが必要になった場合の流れは以下の通りです。
![cookie1](https://p79.tr0.n0.cdn.getcloudapp.com/items/xQu08npQ/zzz.png?v=af0d5f55f5dccd1960a2727ff4447f47)

ブラウザ側(クライアント側)で送ったデータが必要になった場合、cookieに保存されたsession idをリクエストヘッダに含めてリクエストを投げます。
その結果、サーバは受け取ったsession idに合うデータをブラウザ側(クライアント側)に返します。

**尚、上記例ではリクエストメソッドは`POST`としていますが、これ以外のメソッドでも利用されます。**
**また、session idの保存方法は上述のCookieでの保存方法の他にファイル保存、DB保存などの手段があります。**

##実装
それでは実装していきましょう

###構成
```
index.php        // 入力画面です
index.html       // 入力画面用のテンプレートファイルです
confirm.php      // 入力画面で入力されたデータを受け取り、データを表示します
confirm.html     // 確認画面用のテンプレートです
complete.php     // 確認画面からデータを受け取りメール送信し、完了画面を表示します
complete.html    // 完了画面のテンプレートです
```

####index.php
```php:index.php
<?php
	session_start();

	$name = "";
	$mail = "";
	$toiawase = "";
	$errorName = "";
	$errorMail = "";
	$errorToiawase = "";

	if(isset($_SESSION['name']) && isset($_SESSION['mail']) && isset($_SESSION['toiawase'])){
		$name = !is_null($_SESSION['name']) ? $_SESSION['name'] : "";
		$mail = !is_null($_SESSION['mail']) ? $_SESSION['mail'] : "";
		$toiawase = !is_null($_SESSION['toiawase']) ? $_SESSION['toiawase'] : "";
	}

	if(isset($_SESSION['error_name']) && isset($_SESSION['error_mail']) && isset($_SESSION['error_toiawase'])){
		$errorName = $_SESSION['error_name'] ? 1 : 0;
		$errorMail = $_SESSION['error_mail'] ? 1 : 0;
		$errorToiawase = $_SESSION['error_toiawase'] ? 1 : 0;
	}

	require("index.html");
```
`session_start();` この関数でセッション処理を開始します。
その後、このお問い合わせフォームで使用するセッション値がセットされているかチェックしています。

####index.html
```html:index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>phpでフォーム送信</title>
</head>
<body>
<form action="./confirm.php" method="post">
    <div id="contents">
        <div id="name">
          お名前　<input type="text" name="name" value="<?php echo $name; ?>">
          <?php if($errorName) echo "入力に誤りがあります"; ?>
        </div>
        <div id="mail">
          メールアドレス　<input type="text" name="mail" value="<?php echo $mail; ?>">
          <?php if($errorMail) echo "入力に誤りがあります"; ?>
        </div>
        <div id="toiawase">
          お問い合わせ内容　<textarea name="toiawase"><?php echo $toiawase; ?></textarea>
          <?php if($errorToiawase) echo "入力に誤りがあります"; ?>
        </div>
        </br>
        </br>
        <input type="submit" value="確認">
    </div>
</form>
</body>
</html>
```
`<?php if($errorName) echo "入力に誤りがあります"; ?>` これはこの先の`confirm.php`で入力エラーがある、と判断された場合にエラー用のセッション値に値が入ります。このエラー用のセッション値が空でなかった場合に、エラー文字列`入力に誤りがあります`を表示しています。（もちろんエラー文字列は好きなものを設定可能です）

####confirm.php
```php:confirm.php
<?php
    session_start();

    $name = validateData("name");
    $mail = validateData("mail");
    $toiawase = validateData("toiawase");

    if(!filter_var($mail, FILTER_VALIDATE_EMAIL)){
        $_SESSION['error_mail'] = 1;
    }

    if($_SESSION['error_name'] || $_SESSION['error_mail'] || $_SESSION['error_toiawase']){
        header("Location: ./index.php");
        exit();
    }

    require('confirm.html');

    function validateData($key){
        if(is_null($_POST["$key"]) || empty($_POST["$key"]) || !is_string($_POST["$key"])){
            $_SESSION["$key"] = $_POST["$key"];
            $_SESSION["error_" . $key] = 1;
            return "";
        }else{
            $_SESSION["$key"] = $_POST["$key"];
            $_SESSION["error_" . $key] = 0;
            return $_POST["$key"];
        }
    }
```
`confirm.php` ではまず入力画面で入力されたデータのチェックを行います。ここでは`validateData`という関数を使って「名前」「メールアドレス」「問い合わせ内容」のチェックを行っています。
チェックの結果、エラーがあった場合エラー用のセッション値に`1`を代入しています。
`if($_SESSION['error_name'] || $_SESSION['error_mail'] || $_SESSION['error_toiawase'])`
こちらの分岐で入力エラー時は`index.php`に戻す(リダイレクトさせる)ためです。
入力エラーがなければ、次の`confirm.html`を読み込み表示します。

####confirm.html
```html:confirm.html
<!DOCTYPE html>
<html>
<head>
<meta charset='UTF-8'>
<title>確認画面</title>
</head>
	<body>
		お名前：<?php echo $name; ?>
		</br>
		メールアドレス：<?php echo $mail; ?>
		</br>
		お問い合わせ内容
		</br>
		<?php echo $toiawase; ?>
		</br>
		</br>
		<form action='./complete.php' method='post'>
			<input type='button' onclick='history.back()' value='戻る'>
			<input type='submit' value='確認'>
		</form>
	</body>
</html>
```
`confirm.html`では入力画面で入力されたデータを表示します。

####complete.php
```php:complete.php
<?php
    session_start();

    $name = $_SESSION['name'];
    $mail = $_SESSION['mail'];
    $toiawase = $_SESSION['toiawase'];

    $mailHeader = "From: from@from.com";
    $mailSubject = "お問い合わせありがとうございます";
    $mailBody = $name . "様 お問い合わせありがとうございます";
    $mailBody .= "¥n";
    $mailBody .= "ご返信まで～～～～";

    mail($mail, $mailSubject, $mailBody, $mailHeader);

    require("./complete.html");

    $_SESSION = array();
    session_destroy();
```
`complete.php`では入力画面から確認画面へと渡ってきたデータを受け取ってメール送信処理を行ってます。
そして、完了画面を表示しています。
最後に`$_SESSION = array();` `session_destroy();`という処理がありますが、前者ではプログラム内の`$_SESSION`内のデータを消しています。後者ではサーバ上のセッションデータを削除しています。

####complete.html
```html:complete.html
<!DOCTYPE html>
<html>
<head>
<meta charset='UTF-8'>
<title>Insert title here</title>
</head>
	<body>
		<?php echo $name; ?>さん、お問い合わせありがとうございます。
	</body>
</html>
```
すみません、、、、「ありがとうございます」だけを表示するテンプレートです。。。


#終わりに
4回~~もつかって~~にわたってPHPでの「お問い合わせフォーム」を作成しました。
[その１](https://qiita.com/hotate_chan/items/b8ac6b270eac50b0b8e2)　では、ただ動くものを作りました。
[その２](https://qiita.com/hotate_chan/items/dc95f9880f6a1dfa3490)　では、PHPとHTMLを分けました(テンプレート化しました)
[その３](https://qiita.com/hotate_chan/items/64c3a50b1eb490ccfc71)　では、入力チェックを行いました。
そして今回で セッション処理 を使うようにしました。
とりあえず、この「お問い合わせフォーム」は今回で終了です。内容におかしなところがあったらコメントでご指摘お願いします。


#次は何やる？
この「お問い合わせフォーム」の味気ない画面をなんとかするべく`bootstrap`を使ってちょっとはマシなものにしようかと思いましたが、フロントエンドはど素人なのでやめておきます。
ローカルでの **開発環境の構築** か **Laravelの導入** か **jQuery** やろうと思います~~今更jQuery???~~