Developer

魁!小野の塾 小さな管理機能を作ってみようの巻 第20話
2021.08.26
Lv2

魁!小野の塾 小さな管理機能を作ってみようの巻 第20話

小さな管理機能を作ってみよう 第20話

初心者向け、PHPプログラム構築講座です。
初心者といっても、PHPの勉強を少し行い、LAMP環境が自分で構築でき、少しアプリケーションを作成しているレベルを対象とします。
まったくの初心者の場合は、わからない部分が出てくると思います。
できるだけ細かく説明は入れていきますが、説明がわからない場合は、PHPやMySQLの初心者講座をご覧ください。

対象のスキルレベル

  • LAMP環境の構築
  • PHP言語が読める
  • HTML, CSS, Javascriptが少しわかる
  • Bootstrapのドキュメントをみて、HTMLが書ける
  • Ajax(非同期通信)を利用したことがある
  • SESSIONを利用したことがある

構築環境

  • Windows10
  • XAMPP(PHP7.3.2, MariaDB 10.1.38)

ユーザ登録実装

ログイン機能を実装するためにも先にユーザを登録する必要があります。まずはユーザ登録から実装していくのですが、ユーザを登録するためには部署が必要になります。ひとまず部署は固定で登録し、あとで変更しようかと思います。
Javascriptの実装を行ったので、metaタグが必要だということがお分かりかと思いますが、processとmethodを保持するmetaタグの追加、各入力項目にname属性の追加の2つをHTMLに行っていきます。

まずは、metaタグを追加します。

usersEdit.html(抜粋)
<!doctype html>
<html lang="ja" >
<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
	<meta name="process">
	<meta name="method">
	<title>ユーザ管理 | tech.pjin.jp</title>

	<!-- Bootstrap CSS -->
	<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
	<!-- Font Awesome CSS -->
	<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.1.0/css/all.css" integrity="sha384-lKuwvrZot6UHsBSfcMvOkWwlCMgc0TaWr+30HWe3a4ltaBwTZhyTEggF5tJv8tbt" crossorigin="anonymous">
	<!-- Animate.css CSS -->
	<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css" />
	<!-- Sawarabi Gothic -->
	<link href="https://fonts.googleapis.com/css?family=Sawarabi+Gothic" rel="stylesheet">

	<link rel="stylesheet" href="assets/css/style.css" />
</head>

続いて、入力フォームに名前を付けていきます。名前がないとリクエストで飛ばせません。ID属性を指定しているので、これを使えばname属性をJavascriptで付けることも可能なのですが、serializeArray を呼ぶ関係から名前を付けておきます。
リクエストで送信できるのは、input, select, textarea要素になります。

usersEdit.html(抜粋)
<main class="contents">
	<section class="container-fluid">
		<header>
			<h1><i class="fas fa-id-card-alt"></i> ユーザ管理</h1>
		</header>

		<form class="needs-validation">
			<div class="row">
				<div class="col-lg mb-3">
					<div class="form-floating">
						<input type="text" class="form-control" id="name" name="name" placeholder="名前を入力してください。" pattern=".{2,}" required>
						<label for="name">名前</label>
						<div class="valid-feedback">正しい入力です</div>
						<div class="invalid-feedback">正しく入力してください</div>
					</div>
				</div>
			</div>
			<div class="row">
				<div class="col-lg mb-3">
					<div class="form-floating">
						<input type="email" class="form-control" id="mail" name="mail" placeholder="メールアドレスを入力してください。" required>
						<label for="mail">メールアドレス</label>
						<div class="valid-feedback">正しい入力です</div>
						<div class="invalid-feedback">正しく入力してください</div>
					</div>
				</div>
				<div class="col-lg mb-3">
					<div class="form-floating">
						<input type="password" class="form-control" id="passwd" name="passwd" placeholder="パスワードを入力してください。" pattern="(?=.*?[a-z])(?=.*?[A-Z])(?=.*?\d)[a-zA-Z\d]{6,}" required>
						<label for="passwd">パスワード</label>
						<div class="valid-feedback">正しい入力です</div>
						<div class="invalid-feedback">正しく入力してください(英数大文字・小文字、半角数字いずれも含む6文字以上)</div>
					</div>
				</div>
			</div>
			<div class="row">
				<div class="col-lg mb-3">
					<div class="form-floating">
						<input type="tel" class="form-control" id="tel" name="tel" placeholder="電話番号を入力してください。" pattern="\d{2,4}-?\d{3,4}-?\d{3,4}" required>
						<label for="tel">電話番号</label>
						<div class="valid-feedback">正しい入力です</div>
						<div class="invalid-feedback">正しく入力してください</div>
					</div>
				</div>
				<div class="col-lg mb-3">
					<div class="form-floating">
						<select class="form-select" id="dept_id" name="dept_id" required>
							<option value="">選択してください</option>
							<option value="1">経理</option>
							<option value="2">人事</option>
							<option value="3">総務</option>
							<option value="4">営業第1課</option>
							<option value="5">営業第2課</option>
							<option value="6">営業第3課</option>
						</select>
						<label for="dept_id">所属部署</label>
						<div class="valid-feedback">正しい入力です</div>
						<div class="invalid-feedback">正しく入力してください</div>
					</div>
				</div>
			</div>
			<div class="row">
				<div class="col-lg mb-3">
					<div class="form-floating">
						<input type="text" class="form-control" id="addr" name="addr" placeholder="住所を入力してください。" pattern=".{5,}" required>
						<label for="addr">住所</label>
						<div class="valid-feedback">正しい入力です</div>
						<div class="invalid-feedback">正しく入力してください</div>
					</div>
				</div>
			</div>
			<div class="row">
				<div class="col-lg mb-3">
					<button class="btn btn-success"><i class="far fa-check-circle"></i> 登録</button>
				</div>
			</div>
		</form>

	</section>
</main>

Javascriptの実装前にControllerを作成していきたいと思います。

ユーザ管理用Controller実装

Controllerは api フォルダー内に実装します。index.phpがリクエストを受け、Controllerにprocessを渡すと、指定ファイルを読込、methodで実行する関数を決定します。
ユーザ管理の登録処理から作成しますので、Users.phpinsert という関数を指定していきたいと思います。

まず、apiフォルダーに、Users.php を作成してください。

/api/Users.php
<?php
class Users {
	use Result;

	/* $conはController側で作成し各機能へ配布されます。ここではクローズしません。 */
	function insert($con, $request){
		$sql	= "insert into users(name, mail, tel, addr, dept_id, hash, modified) values (?, ?, ?, ?, ?, ?, current_timestamp)";
		/* パスワードは、password_hash関数を利用して作成します。 */
		$hash	= password_hash($request['passwd'], PASSWORD_BCRYPT);
		/* プリペアードステートメントを作成します */
		if($stmt = $con->prepare($sql)){
			/* ?(プレースフォルダー)に値を設定します */
			$stmt->bind_param("ssssis",
				$request['name'],
				$request['mail'],
				$request['tel'],
				$request['addr'],
				$request['dept_id'],
				$hash
			);
			/* SQLを実行します */
			$stmt->execute();
			$stmt->close();
			/* TraitのResultに設定してある成功を実行 */
			$this->success();
		}
		/* TraitのResultに設定してある返却用配列を返します */
		return $this->result();
	}
}
?>

Usersクラスを作成します。まずは登録処理(insert)だけの実装です。ControllerからDBへのConnectionとRequestパラメータが渡されます。
Controllerの実装は、小さな管理機能を作ってみようの巻 第17話 を参照してください。

プリペアードステートメントを作成し、プレースフォルダー(?)に値をバインドして、SQLを実行する流れです。
パスワードのHASH化は、password_hash 関数を利用します。

※参考 password_hash
※参考 PHP, パスワードのハッシュはpassword_hash()を使おう!

登録ボタン押下時のJavascript実装

Controllerも作成し、HTMLの必用な要素を定義し終わりましたので、動かすJavascriptを作成していきます。
usersEdit.html内に、script要素を作成し、実装していきます。

usersEdit.html(抜粋)
	<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
	<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js" integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW" crossorigin="anonymous"></script>
	<script src="assets/js/script.js"></script>
<!-- script要素は、assets/js/script.jsの後に書いていきます -->
<script>
$(function(){
	/* processをUsersに設定します。(/api/Users.phpを読み込むため) */
	$process('Users');

	/* class="btn-success" を指定してある要素をクリックしたら */
	$('.btn-success').on('click', function(){
		/* 登録処理を実行(insertを実行します) */
		$method('insert');
		/* 非同期通信を呼び出し、成功したらusers.htmlへ遷移します */
		$xhr($('form:first'), function(data, status, xhr){
			location.href	= 'users.html';
		});
		/* ボタンを押下した際の戻り値にfalseを返すと、submitしません */
		return false;
	});
});
</script>

ブラウザを開き、http://localhost/usersEdit.html を実行し、各項目に値を入力後、登録ボタンを押下し、users.htmlへ遷移したら登録完了のはずです。


各入力項目に値を入れて、登録ボタンを押下してください。


phpMyAdminを起動して、データベースのusersに値が入っているかを確認してください。
パスワードは暗号化されていると思います。同じパスワードでも再度実行すると別の値になっています。

ここまでで、登録部分の実装がひとまず終了です。次回からは、ログイン処理を実装していきたいと思います。

魁!小野の塾