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外に設置

以上基本的なログイン処理でした。

未経験でも気軽に!サブスク型プログラミングスクール

現役エンジニアの講師へチャット質問し放題のプログラミングスクール【Freeks】

コメントを残す

PHP

前の記事

PDO接続