PHPでフレームワークを使わずに掲示板アプリを作ってみる③　DB登録

# はじめに
※自身の学習を記事に投稿することでアウトプットするのが目的です。
「よくわかるPHPの教科書」のchapter6に書いてある通りにアプリを
作成していくので、私と同じような駆け出しエンジニアの皆さんは、
書籍を買ってアプリを作っていただいた方がわかりやすいかもしれません。


# 使用しているエディタ、実行環境
* VS Code
* XAMPP

* PHP7
* windows

## 確認画面にセッション情報を保存して表示する。
```
<form action="" method="post">
	<input type="hidden" name="action" value="submit" />
	<dl>
		<dt>ニックネーム</dt>
		<dd>
		<?php echo htmlspecialchars( $_SESSION['join']['name'] , ENT_QUOTES);?>
        </dd>
		<dt>メールアドレス</dt>
		<dd>
	    <?php echo htmlspecialchars( $_SESSION['join']['email'] , ENT_QUOTES);?>
        </dd>
		<dt>パスワード</dt>
		<dd>
			【表示されません】
        </dd> 
		<dt>写真など</dt>
		<dd>
		<img src="../member_picture/<?php echo htmlspecialchars( $_SESSION['join']['image'] , ENT_QUOTES);?>" width="100" alt="" />
        </dd>
    </dl>
	<div><a href="index.php?action=rewrite">&laquo;&nbsp;書き直す</a> 
	| 
	<input type="submit" value="登録する" /></div>

</form>
```
:::note info
check.phpに追加で挿入してください。
:::

## 書き直しの機能を追加する
```
		$_SESSION['join']['image'] = $image;
		header('Location: check.php');
		exit();
	}
}
if ( $_REQUEST['action'] == 'rewrite') {
	$_POST = $_SESSION[ 'join' ];
	$error = [ 'rewrite' ] == true;
}
```
:::note info
index.phpの冒頭にプログラムを追加してください。
:::

check.phpで記載したacton=rewriteの値が返ってきた場合、
セッション情報を$_POSTに格納してinputの中に返します。

#### $error = [ 'rewrite' ] == true;
ファイルアップロードのカラムは値を再現できないため、
再度写真を選択してもらう必要があります。
「恐れ入りますが、再度画像を選択してください」
このエラーメッセージを出すために意味のない変数を定義しています。

## DBに登録する
実際にセッション情報をDBに登録していきます。
その前に、DBに接続するためのプログラムを作っておきましょう。
```
<?php
try {
	$db = new PDO('mysql:dbname=mini_bbs;host=127.0.0.1;charset=utf8', 'root','');
} catch (PDOException $e) {
	echo 'DB接続エラー' . $e -> getMessage();
}
?>
```
:::note info
dbconnect.phpとして保存してください。
:::

```
<?php
session_start();
require('dbconnect.php');

//$_SESSION['join']になにも含まれていなかった場合、入力画面に戻る
if ( !isset($_SESSION['join'])) {
	header( 'Location:index.php');
	exit();
}

if ( !empty($_POST)) {
	//登録処理をする
	$statement = $db -> prepare (' INSERT INTO members SET name=? , email=? , password=? , picture=? , created=NOW()');
	echo $ret = $statement -> execute(array(
	$_SESSION['join']['name'],
	$_SESSION['join']['email'],
	sha1( $_SESSION['join']['password']),
	$_SESSION['join']['image']
	));
	unset( $_SESSION['join']);
    //登録完了画面へ
	header('Location: thanks.php');
	exit();

}
?>
```

:::note info
check.phpの冒頭にプログラムを追加してください。
:::

### 処理の流れ説明
* 変数$statementに、prepareメソッドでSQL文を格納します。この時、セッションから受け取った値を追加したい項目を「？」にしておきます。
* executeメソッドで先ほど「？」にした項目に値を入れていきます。
* unsetメソッドでセッション情報を削除します。（セキュリティ確保のため）
* headerメソッドで登録完了画面へ遷移させます。

#### sha1 ( $SESSION['join']['password'])
sha1ファンクションを使うことで、パスワードを暗号化することができます。
これによりパスワードの安全性を高めます。

## アカウントの重複を確認する。
メールアドレスの重複を確認するプログラムを書いていきます。
```
if ( empty( $error )) {
		$member = $db -> prepare( ' SELECT COUNT(*) AS cnt FROM members WHERE email=? ' );
		$member -> execute( array($_POST['email']));
		$record = $member -> fetch();
		if ( $record[ 'cnt' ] > 0) {
			$error[ 'email' ] = 'duplicate';
		}
	}
```

### 処理の流れ
* $memberに、データベースから指定したメールアドレスの件数を合計し、cntとしてSQLを発行。
* $_POST['email']の内容を上記の　email=?にもってくる。
* record['cnt']で件数を取り出し、この値が１以上である場合は$error['email']にエラーメッセージを格納する。

```
<dd>
			<input type="text" name="email" size="35" maxlength="255" value="<?php echo htmlspecialchars($_POST['email'],ENT_QUOTES);?>" />
            <?php if ( $error['email'] == 'blank'): ?>
			<p class = "error" > * メールアドレスを入力してください </p>
            <?php endif; ?>
			<?php if ( $error['email'] == 'duplicate' ): ?>
			<p class = "error" > * 指定されたメールアドレスはすでに登録されています。</p>
			<?php endif; ?>
```

あとは同じようにエラーメッセージを出力させましょう。