前回は収支データを日付で絞り込みをして検索する機能を実装しました。
今回からは新規ユーザー登録やログイン機能などアカウント周りの機能の実装を行います。
↓前回の記事はこちら
新規ユーザー登録機能の実装
まずは実装する流れを確認します。
- 入力された情報チェック
- 確認画面へ情報を渡して登録する
- 1度入力した情報を保持して書き直し画面へ戻す
入力された情報チェック
入力された情報に重複や不一致がないかのチェックをする処理を実装します。
情報の形式や長さ、空白時のエラーはHTMLのコーディングをした際に付与しているため、今回はこの部分のチェック処理は実装しません。
今回のチェックは「ユーザー名重複」と「パスワードの一致」「ユーザー名とパスワードの同一文字列禁止」の3箇所です。
ユーザー名重複チェック
まずはユーザー名重複のチェック処理を実装します。このチェックは同じユーザー名が登録されることを防ぐためのチェックです。
情報チェックのプログラムはjoinディレクトリ直下のindex.phpに記述していきます。
冒頭にDB接続ファイルとfunctions.phpを読み込むプログラムを記述します。
<?php
require_once('../dbconnect.php');
include_once('../functions.php');
?>
続いて「確認画面へ」が押下されたときに入力した情報を受け取るプログラムを記述します。
if ($_SERVER['REQUEST_METHOD'] === 'POST') :
//フォームデータ格納
$nickname = filter_input(INPUT_POST, 'nickname', FILTER_SANITIZE_SPECIAL_CHARS);
$username = filter_input(INPUT_POST, 'username', FILTER_SANITIZE_SPECIAL_CHARS);
$password = filter_input(INPUT_POST, 'password', FILTER_SANITIZE_SPECIAL_CHARS);
$password_confirm = filter_input(INPUT_POST, 'password_confirm', FILTER_SANITIZE_SPECIAL_CHARS);
$initial_savings = filter_input(INPUT_POST, 'initial_savings', FILTER_SANITIZE_SPECIAL_CHARS);
endif;
$_SERVER[‘REQUEST_METHOD’] === ‘POST’ はポスト送信されたらという条件です。
確認画面へボタンがPOST送信のフォームタグ内、type=submitのinputタグで作っているため、押下することでポスト送信が行われます。
入力された情報を受け取ったら、そのあとにチェック処理を記述します。
ここから先の入力チェックに関するプログラムはすべて$_SERVER[‘REQUEST_METHOD’] === ‘POST’の条件文内に記述していきます。
//ユーザーネーム重複確認
$sql = 'SELECT COUNT(*) FROM user WHERE username = ?'; //入力されたユーザー名のデータの数を抽出するSQL文
$stmt = $db->prepare($sql); //上記SQLをセット
$stmt->bind_param('s', $username); //?の部分に入力されたユーザー名をセット
sql_check($stmt, $db);
$stmt->bind_result($count); //データの数を取得する
$stmt->fetch();
if ($count === 0) : //データの数が0なら
$exist = 'notexist'; //存在しないことを示す文字列をセット
else : //データの数が0以外なら
$exist = 'exist'; //データが存在することを示す文字列をセット
endif;
プログラムの流れは、入力したユーザー名をWHERE文に組み込んだSQLを発行実行します。
ここではCOUNT(*)でデータの数を抽出するので、SQL実行後bind_resultでその結果を取得できます。
そしてSQLの結果(データの数)で$exist変数に文字列をそれぞれセットします。
この変数の値を使ってエラーの処理を記述します。エラー時には、画面遷移を行わずエラーメッセージを入力フォーム上部に表示させます。今はエラーがない状態でも表示されているので、これをまずはユーザー名重複エラーのときのみ表示させます。
<?php if ($exist === 'exist') : ?> <!--追加-->
<section class="p-section p-section__message p-section__message--join">
<div class="p-message-box p-message-box--error">
<p>すでに登録されているユーザー名です。<br>
パスワードが一致しません。<br>
ユーザー名とパスワードは異なる文字列を入力してください。</p>
</div>
</section>
<?php endif; ?> <!--追加-->
エラーメッセージの要素をif文で囲い、条件は先ほどユーザー名重複がある場合に$exist=’exist’とセットした変数を利用します。
ここでエラー処理が正常に動くか確かめるため、phpmyadminから直接userテーブルに情報を入れておきます。
まずは「user」テーブルを作成します。テーブルの構造は以下の通りです。
そして以下の仮データを直接登録します。
上記情報を入れた状態で、同じユーザー名で確認画面へ遷移を試みると下記のようにエラーメッセージ要素が表示されます。
ユーザー名の重複がない場合は何も表示されません。
以上でユーザー名の重複チェック処理は完了です。
パスワードの一致チェック
続いて入力欄の「パスワード」と「確認用パスワード」が一致するかをチェックする処理を実装します。
以下のプログラムを先程のユーザー名重複の下に追記します。
//パスワード一致確認
if ($password !== $password_confirm) :
$password_match = 'notmatch';
else :
$password_match = 'match';
endif;
送られてきたデータをセットした変数を比較し、文字列が一致する場合と不一致の場合にそれぞれ変数に文字列をセットします。
それではこの値を使ってエラーメッセージを表示する条件を追加していきます。
<?php if ($exist === 'exist' || $password_match === 'notmatch') : ?> <!--条件文追加-->
<section class="p-section p-section__message p-section__message--join">
<div class="p-message-box p-message-box--error">
<!--エラーによってテキストを変える-->
<?php if ($exist === 'exist') : ?>
<p>すでに登録されているユーザー名です。</p>
<?php endif; ?>
<?php if ($password_match === 'notmatch') : ?>
<p>パスワードが一致しません。</p>
<?php endif; ?>
<p>ユーザー名とパスワードは異なる文字列を入力してください。</p>
</div>
</section>
<?php endif; ?>
エラーメッセージを出す条件に追加して、エラーテキストも変数によって出し分けます。
この段階でのエラー処理は以下のようになります。
両方にエラーが有る場合はすべてのエラーメッセージが表示されます。
以上でパスワードの不一致エラー処理は完了です。
ユーザー名とパスワードの同一文字列禁止チェック
このチェックはユーザー名と同じ文字列のパスワードで登録することを禁止するチェックです。
以下のプログラムをパスワード不一致エラー処理の下に追記します。
//ユーザー名とパスワードが異なる文字列か
if ($username === $password) :
$samestr = "same";
else :
$samestr = "different";
endif;
内容は先程のパスワード不一致の処理と同様です。
それではこの変数を使ってエラーメッセージの条件を修正していきます。
<?php if ($exist === 'exist' || $password_match === 'notmatch' || $samestr === 'same') : ?><!--条件追加-->
<section class="p-section p-section__message p-section__message--join">
<div class="p-message-box p-message-box--error">
<?php if ($exist === 'exist') : ?>
<p>すでに登録されているユーザー名です。</p>
<?php endif; ?>
<?php if ($password_match === 'notmatch') : ?>
<p>パスワードが一致しません。</p>
<?php endif; ?>
<?php if ($samestr === 'same') : ?>
<p>ユーザー名とパスワードは異なる文字列を入力してください。</p>
<?php endif; ?>
</div>
</section>
<?php endif; ?>
以上ですべての入力チェックは完了です。
チェック処理は完了しましたが、現状1度入力した値が消えてしまいます。エラーとなった場合でも入力した値を残すように実装します。
<!--ニックネーム入力のinput-->
<input type="text" name="nickname" id="nickname" value="<?php echo h($nickname);?>" required>
<!--ユーザー名入力のinput-->
<input type="text" name="username" id="username" value="<?php echo h($username);?>" required>
<!--パスワード入力のinput-->
<input type="password" name="password" id="password" value="<?php echo h($password);?>" required>
<!--貯蓄額入力のinput-->
<input type="number" name="initial_savings" id="initial_savings" value="<?php echo h($initial_savings);?>">
それぞれのinputタグのvalue属性にPOST送信で受け取った値を出力しています。
確認用パスワードも出力することができますが、今回はパスワードの方だけ復元しています。
以上で入力チェックとエラー時の復元の実装が完了しました。
確認画面へ情報を渡して登録する
入力チェックで問題がなければ確認画面へ遷移するよう実装します。
以下を入力チェックプログラムの下に追記します。
endif; //if ($_SERVER['REQUEST_METHOD'] === 'POST') の閉じendif
//以下を追加
if ($exist === 'notexist' && $password_match === 'match' && $samestr === "different") :
header('Location: confirm.php');
exit();
endif;
確認画面へ遷移できる条件として、ユーザー名重複なし&パスワードと確認用パスワードの一致&ユーザー名とパスワードが異なる文字列であるという条件をおき、trueとなるときにheader関数で確認画面へ遷移する処理となっています。
正常に遷移したのが確認できたら、確認画面に入力した値を出力するようにします。
ここではPOST送信の遷移ではなく、header関数での遷移なので、セッションを使って情報を復元する必要があります。
まずはheader関数で遷移する前にセッションに入力した値を保存するプログラムを追記します。
//共通ファイルの読み込みの上に以下1行を追記
session_start();
//確認画面へ遷移
if ($exist === 'notexist' && $password_match === 'match' && $samestr === "different") :
//以下を追記
$_SESSION['nickname'] = $nickname;
$_SESSION['username'] = $username;
$_SESSION['password'] = $password;
$_SESSION['initial_savings'] = $initial_savings;
//ここまで
header('Location: confirm.php');
exit();
endif;
ファイル冒頭でセッションを使うことを宣言します。そしてheader()関数の前に $_SESSION[‘保存する箱の名前’] = 保存する値 という形式でセッションに値を保存することができます。
セッションに保存して遷移することができるようになったので、次は確認画面で送られてきたセッションを受け取って出力します。
まずはいつも通り共通ファイルの読み込みとセッションを使う宣言をファイル冒頭に記述します。
<?php
session_start();
require_once('../dbconnect.php');
include_once('../functions.php');
?>
続いて全てのセッションがセットされている場合にはそれを受け取り変数にセットします。
セッションがない場合はjoin/index.phpに強制的に戻します。
//セッションがあれば値を格納、なければindex.phpに戻す
if (isset($_SESSION['nickname']) && isset($_SESSION['username']) && isset($_SESSION['password']) && isset($_SESSION['initial_savings'])) :
$nickname = $_SESSION['nickname'];
$username = $_SESSION['username'];
$password = $_SESSION['password'];
$initial_savings = $_SESSION['initial_savings'];
else :
header('Location: index.php');
exit();
endif;
上記の条件分岐で、直接確認画面のURLへ遷移を試みても新規ユーザー登録画面へ戻されます。
それでは渡された値を出力しています。
<!--書き換え前-->
<p>【ニックネーム】</p>
<p>【ユーザー名】</p>
<p>【100,000円】</p>
<!--書き換え後-->
<p>【<?php echo h($nickname); ?>】</p>
<p>【<?php echo h($username); ?>】</p>
<p>【<?php echo $initial_savings !== '' ? number_format(h($initial_savings)) . '円' : '未登録'; ?>】</p>
ニックネームとユーザー名はそのまま出力しますが、貯蓄額は任意入力のため三項演算子で値がセットされているときはその値を、入力されなかった場合には「未登録」という文字を出力しています。
また今回はパスワードはセキュリティの観点からセッションとして受け取っていますが画面に出力はしません。
続いて確認画面の「登録する」からuserテーブルに情報を登録する処理を実装します。
データベースへの追加プログラムは同じくconfirm.phpに記述していきます。
//登録ボタン押下でデータを登録
if ($_SERVER['REQUEST_METHOD'] === 'POST') :
$sql = 'INSERT INTO user(nickname, username, password, initial_savings) VALUES(?, ?, ?, ?)';
$stmt = $db->prepare($sql);
$encryption = password_hash($password, PASSWORD_DEFAULT);
$stmt->bind_param('sssi', $nickname, $username, $encryption, $initial_savings);
sql_check($stmt, $db);
unset($_SESSION['nickname'], $_SESSION['username'], $_SESSION['password'], $_SESSION['initial_savings']);
header('Location: thanks.php');
endif;
登録ボタンがtype=submitのinput要素なので、登録を押下するとPOST送信が行われます。
なのでデータベースの登録プログラムは、POST送信がされたらという条件文の中に記述します。
条件文内のプログラムですが、SQLの発行とセットはこれまでと同じパターンです。
続いて、パスワードを登録する際にそのままの文字列で登録するのはセキュリティ的に危険なので暗号化をする必要があります。
password_hash(‘暗号化するパスワード’ , PASSWORD_DEFAULT)で暗号化することができます。
password_hash() – 公式ドキュメント
暗号化したパスワードを変数にセットし、bind_paramでデータベースに入れる情報をセットします。
その後いつものSQLエラーチェックを挟んだあと、登録完了画面に遷移する前にセッションをクリアします。
セッションのクリアは、unset($_SESSION[‘キーネーム’]) でクリアすることができます。セッションが残ったまま遷移をすると確認ページに再度アクセスできてしまうなどバグを起こす原因になってしまいます。
セッションのクリアができたらheader関数で登録完了ページに遷移します。
正常に登録することができました。
続いて修正するボタンが押されたときの処理を実装します。
1度入力した情報を保持して書き直し画面へ戻す
現状、確認画面の修正するボタンを押下すると新規ユーザー登録画面に戻りますが、入力した値は消えてしまいます。
修正するを押した際、1度入力していた値を保持したまま元のページに戻すためにセッションを使います。
まずは修正するボタンのhref属性にmode=modifyというパラメータをつけます。
<!--70行目付近-->
<a class="c-button c-button--bg-gray" href="./index.php?mode=modify">修正する</a>
パラメータを追加して遷移するとURLにパラメータが付いて遷移するようになります。
これを利用して、パラメータが付いているときにはセッションの値を受け取って情報を復元するように実装していきます。
以下をjoin/index.phpの共通ファイルの読み込みの下、入力チェック処理の上に追記します。
//書き直しモードでセッション内容を復元
if (isset($_GET['mode']) && $_GET['mode'] === 'modify' && isset($_SESSION['nickname'], $_SESSION['username'], $_SESSION['password'], $_SESSION['initial_savings'])) :
$nickname = $_SESSION['nickname'];
$username = $_SESSION['username'];
$password = $_SESSION['password'];
$initial_savings = $_SESSION['initial_savings'];
else :
$nickname = '';
$username = '';
$password = '';
$initial_savings = '';
endif;
条件文はmodeパラメータがついている&mode=modifyである&それぞれのセッションがセットされているという条件です。
上記条件がtrueの時、セッションに保存している値を変数にセットします。
これらの変数の出力は入力チェック処理のところですでに記述しているためここで新たに出力のプログラムを記述する必要はありません。
上記を実装することで、修正するボタンを押下して遷移しても情報が復元されます。
以上で新規ユーザー登録の機能の実装は完了です。
最後に
今回は新規ユーザー登録でデータベースにユーザー情報を登録したり、その過程で入力チェックや書き直しができる機能を実装しました。
次回はログインとログアウト機能を実装します。
最後までお読みいただきありがとうございました。
コメント