PHPログイン機能実装
データベースを活用したログイン機能を実装していきます。
今回はIDとPasswordでログインする機能を実装していきます。
ファイル構成は以下のようにしました。
web/
┣ admin/
┣ register.php
┣ signup.php
┣ dbc.php
┣ index.php
┣ login.php
データベース設計は以下の通り
※last_name,first_name,email,commentは今回使いませんが…
db名:attend
テーブル名:work
id,int,AI
user_id,varchar
password,varchar
last_name,varchar
first_name,varchar
email,varchar
comment,middumtext ⇒ nullを許可
varcharは適切な文字数を設定します
ユーザー登録画面
admin/signup.php
<?php
session_start();
$user_id = $_SESSION['user_id'];
// 以下の部分はログイン制限しているので、ユーザー登録するまではコメントアウト
// if (isset($_SESSION['user_id'])) {
// $msg = '現在' . $user_id . 'でログインしています。';
// } else {
// header('Location: ../login.php');
// }
?>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>新規登録</title>
</head>
<body>
<p><?php echo $msg ?></p>
<h1>新規登録</h1>
<form action="register.php" method="POST">
<p><input type="text" name="user_id" placeholder="ユーザーID"></p>
<p><input type="password" name="password" placeholder="パスワード"></p>
<p><input type="text" name="last_name" placeholder="姓"></p>
<p><input type="text" name="first_name" placeholder="名"></p>
<p><input type="email" name="email" placeholder="email"></p>
<p><textarea name="comment" id=""></textarea></p>
<input type="submit" value="登録">
</form>
</body>
</html>
ユーザー登録処理
<?php
require_once '../dbc.php';
$user_id = $_POST['user_id'];
$password = password_hash($_POST['password'], PASSWORD_DEFAULT);
$last_name = $_POST['last_name'];
$first_name = $_POST['first_name'];
$email = $_POST['email'];
$comment = $_POST['comment'];
try {
$dbh = dbConnect();
} catch (PDOException $e) {
echo '接続に失敗しました' . $e->getMessage();
}
$sql = "SELECT * FROM work WHERE user_id = :user_id";
$stmt = $dbh->prepare($sql);
$stmt->bindValue(':user_id', $user_id, PDO::PARAM_STR);
$stmt->execute();
$member = $stmt->fetch();
if ($member) {
$msg = 'ユーザーIDがかぶっています。';
} else {
$sql = 'INSERT INTO work(user_id, password, last_name, first_name, email, comment) VALUES (:user_id, :password, :last_name, :first_name, :email, :comment)';
$stmt = $dbh->prepare($sql);
$stmt->bindValue(':user_id', $user_id, PDO::PARAM_STR);
$stmt->bindValue(':password', $password, PDO::PARAM_STR);
$stmt->bindValue(':last_name', $last_name, PDO::PARAM_STR);
$stmt->bindValue(':first_name', $first_name, PDO::PARAM_STR);
$stmt->bindValue(':email', $email, PDO::PARAM_STR);
$stmt->bindValue(':comment', $comment, PDO::PARAM_STR);
$stmt->execute();
$msg = 'ユーザー情報が登録されました。';
}
?>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ユーザー登録完了</title>
</head>
<body>
<h3><?php echo $msg ?></h3>
</body>
</html>
ログインPHPに簡単なひな形
今回はトップページにログイン制限をかけます。
<?php
session_start();
$user_id = $_SESSION['user_id'];
if (isset($_SESSION['user_id'])) {
$msg = '現在' . $user_id . 'でログインしています。';
} else {
header('Location: login.php');
}
?>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>トップページ</title>
</head>
<body>
<h1>トップページ</h1>
<p><?php echo $msg ?></p>
<p><a href="admin/signup.php">ユーザー登録</a></p>
<p><a href="logout.php">ログアウト</a></p>
</body>
</html>
ログイン画面を実装します。
<?php
require_once 'dbc.php';
session_start();
$err = array();
try {
$dbh = dbConnect();
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$user_id = $_POST['user_id'];
$password = $_POST['password'];
if (!$user_id) {
$err['user_id'] = 'ユーザーIDを入力してください';
}
if (!$password) {
$err['password'] = 'パスワードを入力してください';
}
if (empty($err)) {
$sql = "SELECT * FROM work WHERE user_id = :user_id";
$stmt = $dbh->prepare($sql);
$stmt->bindValue(':user_id', $user_id, PDO::PARAM_STR);
$stmt->execute();
$member = $stmt->fetch(PDO::FETCH_ASSOC);
if (password_verify($password, $member['password'])) {
$_SESSION['user_id'] = $user_id;
header('Location: index.php');
exit;
} else {
echo '認証に失敗しました';
}
} else {
$user_id = "";
$password = "";
}
}
} catch (PDOException $e) {
echo 'データベース接続に失敗しました' . $e->getMessage();
}
?>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h2>Login</h2>
<form action="login.php" method="POST">
<p><input type="text" name="user_id" placeholder="ユーザーID"></p>
<div><?php if ($err) echo $err['user_id'] ?></div>
<p><input type="text" name="password" placeholder="パスワード"></p>
<div><?php if ($err) echo $err['password'] ?></div>
<p><input type="submit" value="ログイン"></p>
</form>
</body>
</html>
未入力でログインを押すと、エラーがひょうじされるようになりました。
データベース接続用のdbc.phpを作成し、以下の関数を用意
<?php
require_once 'config.php';
function dbConnect()
{
$dsn = 'mysql:host=' . DB_HOST . ';dbname=' . DB_NAME . ';charset=utf8';
$user = DB_USER;
$password = DB_PASSWORD;
try {
$dbh = new PDO($dsn, $user, $password, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
]);
return $dbh;
} catch (PDOException $e) {
header('Location: err.php');
exit;
}
}
登録したログインした人のデータベース情報を取得できるか、var_dumpで確認してみます。
別途config.phpを作成し、ファイルはDB情報に該当するので、本番環境ではPublic外に設置
以上基本的なログイン処理でした。