前回はデータ登録削除編集のプログラムを修正しました。
今回はアカウントページにユーザー情報を出力し、ユーザー情報を更新できるように実装していきます。
↓前回の記事はこちら
今回の流れとしてはまず「アカウントページに情報を出力」→「アカウント情報更新機能実装」の2ステップで進めていきます。
アカウントページに情報を出力
現在アカウントページは以下のように仮の情報をそのままコードに記述しています。
パスワード以外の情報をユーザーごとの情報になるように実装します。
//冒頭に追加
include_once('./functions.php');
//情報出力部分
<p>山田</p> <!--書き換え前-->
<p><?php echo h($nickname); ?></p> <!--書き換え後-->
<p>yamada</p> <!--書き換え前-->
<p><?php echo h($username);?></p> <!--書き換え後-->
<p>1,000,000円</p> <!--書き換え前-->
<p><?php echo h($initial_savings !== '' ? number_format($initial_savings) . '円' : '未登録'); ?></p>
ニックネームやユーザー名はそのままセッションの値を出力します。
しかし貯蓄額は任意入力のため、三項演算子で登録がない場合は未登録と出力します。そして登録がある場合は、number_format関数で最後に「円」をつけて出力します。
以上でアカウント情報の出力は完了です。
アカウント情報更新機能
まずは変更を押すと編集モーダルが出るようにします。
編集モーダル実装
今回は「変更」ボタンを押すとPOST送信がされるので、POST送信が行われたらモーダルを表示するように実装します。
<?php if ($_SERVER['REQUEST_METHOD'] === 'POST') : ?>
<section class="p-section p-section__full-screen">
<form class="p-form p-form--account-edit" action="" method="POST">
<input type="hidden" name="column_value" value="nickname">
<div class="p-form__vertical-input">
<p>現在のニックネーム</p>
<p>山田</p>
<input type="password" name="now_password" required>
</div>
<div class="p-form__vertical-input">
<p>新しいニックネーム※12文字以内</p>
<input type="" name="modify_value" required>
</div>
<div class="p-form__center">
<a class="c-button" href="./account.php">キャンセル</a>
<input class="c-button c-button--bg-blue" type="submit" name="modify" value="変更する">
</div>
</form>
</section>
<?php endif; ?>
まずはaccount.phpのコメントアウトを解除し、その部分をif文で囲います。
これで変更ボタンを押したときに編集モーダルが表示されます。
続いてモーダル内を押されたボタンによって表示するテキストやinputを変えます。
まずはif文の条件を追加します。
<!--39行目付近 書き換え-->
<?php if (($_SERVER['REQUEST_METHOD'] === 'POST') && (isset($_POST['modify_nickname']) || isset($_POST['modify_username']) || isset($_POST['modify_password']) || isset($_POST['modify_initial_savings']))) : ?>
複雑ですが、まずはPOST送信であることそしてボタン1つ1つにname属性をセットしているので、それがあるかの且つ条件です。
そしてif文の下に以下を記述します。
<?php
if (isset($_POST['modify_nickname'])) {
$item_label = "ニックネーム";
$column = "nickname";
$caution = "※12文字以内";
$modify_item = $_POST['nickname'];
} elseif (isset($_POST['modify_username'])) {
$item_label = "ユーザー名";
$column = "username";
$caution = "※半角英数字6〜12文字";
$modify_item = $_POST['username'];
} elseif ($_POST['modify_password']) {
$item_label = "パスワード";
$column = 'password';
$caution = "※半角英数字6〜12文字";
$modify_item = "非表示";
} elseif (isset($_POST['modify_initial_savings'])) {
$item_label = "初期貯蓄額";
$column = "initial_savings";
$modify_item = number_format($_POST['initial_savings']) . '円';
}
?>
モーダルでテキスト出し分けをする際、いちいちif文を記述するのは大変なので変数に予め入れます。
・$item_label・・・新しい〇〇の「〇〇」部分
・$column・・・編集SQLプログラムにパラメータで渡す値
・$caution・・・注意事項(ある項目のみ)
・$modify_item・・・修正前データ
これらの値を使って修正プログラムを1つ1つ実装していきます。
まずは以下の画像赤枠部分です。
<!--書き換え前 65行目付近から-->
<input type="hidden" name="column_value" value="nickname">
<div class="p-form__vertical-input">
<p>現在のニックネーム</p>
<p>山田</p>
<input type="password" name="now_password" required>
<!--書き換え後-->
<input type="hidden" name="column_value" value="<?php echo h($column); ?>">
<div class="p-form__vertical-input">
<p>現在の<?php echo h($item_label); ?></p>
<?php if ($column === 'password') : ?>
<input type="password" name="now_password" required>
<?php else : ?>
<p><?php echo h($modify_item); ?></p>
<?php endif; ?>
画面上では表示されない隠し要素に、どのカラムの情報を編集しようとしているのかを出力します。
そして現在の〇〇には「$item_label」を出力します。
その下にはもしパスワードの編集であれば、input要素を出力し、それ以外の場合はpタグの中に「$modify_item」を出力します。
このままではまだ$modify_itemに渡ってくる値が仮の情報なので、それがモーダルに出力されます。
灰色背景要素の隠しinputのvalue属性にユーザー情報を出力するように修正します。
<!--ニックネーム部分 92行目付近-->
<input type="hidden" name="nickname" id="nickname" value="山田"> <!--書き換え前-->
<input type="hidden" name="nickname" id="nickname" value="<?php echo h($nickname);?>"> <!--書き換え後-->
<!--ユーザー名部分 98行目付近-->
<input type="hidden" name="username" id="username" value="yamada"> <!--書き換え前-->
<input type="hidden" name="username" id="username" value="<?php echo h($username);?>"> <!--書き換え後-->
<!--初期貯蓄額部分 110行目付近-->
<input type="hidden" name="initial_savings" id="initialSavings" value="1000000"> <!--書き換え前-->
<input type="hidden" name="initial_savings" id="initialSavings" value="<?php echo h($initial_savings);?>"> <!--書き換え後-->
以上で変更を押したときに項目に応じた内容が出力されるようになりました。
続いてモーダル内下の部分を修正していきます。
<!--書き換え前 75行目付近から-->
<p>新しいニックネーム※12文字以内</p>
<input type="" name="modify_value" required>
<!--書き換え後-->
<p>新しい<?php echo h($item_label) . h($caution); ?></p>
<!-- どの情報の変更かでinputの入力条件を変える -->
<?php if (isset($_POST['modify_nickname'])) : ?>
<input type="text" name="modify_value" maxlength="12" required>
<?php elseif (isset($_POST['modify_username'])) : ?>
<input type="text" name="modify_value" minlength="6" maxlength="12" pattern="^[0-9a-zA-Z]+$" required>
<?php elseif (isset($_POST['modify_password'])) : ?>
<input type="password" name="modify_value" minlength="6" maxlength="12" pattern="^[0-9a-zA-Z]+$" required>
<?php elseif (isset($_POST['modify_initial_savings'])) : ?>
<input type="number" name="modify_value" required>
<?php endif; ?>
<!-- //どの情報の変更かでinputのtypeを変える -->
「新しい〇〇※注意事項」の部分は、先程上部で実装したときと同様に予め変数に入れていた値を出力しています。
そしてその下のinputは情報によって属性や条件が異なるので、変更ボタンのname属性を条件分岐に用いて適正なinput要素を出力するようにしています。
最後に変更するボタンを、パスワードのときとそれ以外のときで出力を変更します。
これはパスワードの変更では、現在のパスワードとログイン情報が一致するかを確認したあとに変更するためです。
<!--書き換え前 92行目付近-->
<input class="c-button c-button--bg-blue" type="submit" name="modify" value="変更する">
<!--書き換え後-->
<?php if ($column === 'password') : ?>
<input class="c-button c-button--bg-blue" type="submit" name="password_modify" value="変更する">
<?php else : ?>
<input class="c-button c-button--bg-blue" type="submit" name="other_modify" value="変更する">
<?php endif; ?>
画面上は違いはわかりませんが、name属性が異なるinputが出力されます。
以上でモーダルの各出力は完了です。
それでは「変更する」を押下した際の更新プログラムを実装していきます。
更新プログラムはパスワード変更の際だけ、既存のパスワードとの一致処理を挟むのでそちらを実装してから更新プログラムを実装します。
既存のパスワードとの一致処理プログラム
まずは変更モーダルのformタグのアクション属性に「./account-update.php」を指定します。
<form class="p-form p-form--account-edit" action="./account-update.php" method="POST">
「account-update.php」という名前でファイルを作成し、共通ファイルを読み込ませます。
<?php
include_once('./session.php');
require_once('./dbconnect.php');
続いて送られてきたデータを受け取り変数に格納します。
$column_value = filter_input(INPUT_POST, 'column_value', FILTER_SANITIZE_SPECIAL_CHARS);
$modify_value = filter_input(INPUT_POST, 'modify_value', FILTER_SANITIZE_SPECIAL_CHARS);
ここから既存パスワードが一致するかの処理を記述していきます。
まずは$_POST[‘now_password’]がセットされているときを条件式にして、ログイン中のユーザーの既存パスワードをSQLで取得します。
if (isset($_POST['now_password'])) :
$now_password = filter_input(INPUT_POST, 'now_password', FILTER_SANITIZE_SPECIAL_CHARS);
$sql = "SELECT password FROM user WHERE id=? LIMIT 1";
$stmt = $db->prepare($sql);
$stmt->bind_param('i', $user_id);
sql_check($stmt, $db);
$stmt->bind_result($hash_password);
取得した暗号化された既存パスワードは$hash_passwordに格納し取得しました。
パスワードを取得できたら、fetchでデータを回しながら一致するときとしないときの処理を記述していきます。
以下を先程のSQLプログラムの下に続けて記述します。
$stmt->fetch();
//パスワード一致不一致処理
if (password_verify($now_password, $hash_password)) :
$modify_value = password_hash($modify_value, PASSWORD_DEFAULT);
else :
header('Location: ./account.php?dataOperation=pwerror');
exit();
endif;
$stmt->close();
endif;
条件式の「password_verify($now_password, $hash_password)」は暗号化されたパスワードとモーダルで入力された暗号化されていないパスワードを比較し一致ならtrueを、不一致ならfalseを返します。
password_verify関数 – 公式ドキュメント
まずtrueのときは、$modify_valueに新しく入力されたパスワードを暗号化した値を入れ直します。
そして不一致の場合はaccount.phpにdataOperation=pwerrorパラメータを付けて返します。
以上でパスワードの一致不一致処理は完了です。
更新プログラム
最後にUPDATE文でデータベースの情報を更新するプログラムを実装します。
ここからのプログラムはパスワード一致不一致処理の下に続けて記述していきます。
$sql = "UPDATE user SET {$column_value} = ? WHERE id = ?";
$stmt = $db->prepare($sql);
if ($column_value === "initial_savings") :
$stmt->bind_param('ii', $modify_value, $user_id);
else :
$stmt->bind_param('si', $modify_value, $user_id);
endif;
if (!$stmt) :
header('Location: ./account.php?dataOperation=error');
endif;
$success = $stmt->execute();
if (!$success) :
header('Location: ./account.php?dataOperation=error');
endif;
SQLの発行から実行までの流れはこれまでと同様です。
1点、bind_paramで値をセットする際に初期貯蓄額とそれ以外でデータの方が異なるので、条件分岐を展開しています。
正常に更新できたら、セッションを新しいデータに書き換えます。
//セッション修正
if ($column_value === "nickname") :
$_SESSION['nickname'] = $modify_value;
elseif ($column_value === "username") :
$_SESSION['username'] = $modify_value;
elseif ($column_value === "initial_savings") :
$_SESSION['initial_savings'] = $modify_value;
endif;
最後にheader関数でアカウント管理ページにパラメータ付きで戻せば更新プログラムは完了です。
header('Location: ./account.php?dataOperation=update');
exit();
更新成功・失敗時のメッセージ
情報更新に成功・失敗した際にアカウントページにメッセージを表示させます。
この処理は選択項目の編集の際に実装したものと同じです。
まずは「item-edit.php」に記述した、メッセージモーダル部分をコピペします。
そして今回は削除することはないので、
①条件文内の削除条件と出力テキストの「削除しました」の部分をパスワード不一致時の条件とテキストに変更
②「p-message-box」と「c-button」クラスの三項演算子の条件部分にパスワードエラーのパラメータを付け加えます。
そしてOKボタンのリンク先がaccount.phpになるようJS関数の引数を変更します。
<!-- 操作完了コンテンツ -->
<?php if ($_GET['dataOperation'] && ($_GET['dataOperation'] === 'pwerror' || $_GET['dataOperation'] === 'update' || $_GET['dataOperation'] === 'error')) : ?>
<section class="p-section p-section__full-screen" id="doneOperateBox">
<div class="p-message-box <?php echo ($_GET['dataOperation'] === 'error' || $_GET['dataOperation'] === 'pwerror') ? 'line-red' : 'line-blue'; ?>">
<p id="doneText">
<?php
if ($_GET['dataOperation'] === 'error') {
echo '正しく処理されませんでした';
} elseif ($_GET['dataOperation'] === 'pwerror') {
echo '現在のパスワードが一致しません';
} elseif ($_GET['dataOperation'] === 'update') {
echo '更新しました';
}
?>
</p>
<button class="c-button <?php echo ($_GET['dataOperation'] === 'error' || $_GET['dataOperation'] === 'pwerror') ? 'c-button--bg-darkred' : 'c-button--bg-blue'; ?>" onclick="onClickOkButton('');">OK</button>
</div>
</section>
<?php endif; ?>
<!-- //操作完了コンテンツ -->
以上でアカウントページの情報連携と更新プログラムの実装は完了です。
最後に
今回はアカウントページにログイン中のユーザー情報を出力したり、その情報を編集できるように実装しました。
次回はホーム画面データ一覧をエクセルで出力できるようにしたり、合計金額を計算して表示させるような実装をします。
最後までお読みいただきありがとうございました。
コメント