PHPでログイン機能とセッションの基礎

学習目的

  • ログインとログアウトの仕組みを理解する
  • $_SESSION を使ってログイン状態を保持する方法を学ぶ
  • セキュリティの基本(パスワードチェック、セッション破棄)を体験する

フォルダとファイル名

php-db09 フォルダに db09.php と以下のファイルを作成します。
ファイル構成は以下になります。

php-db09/
├── login.php        # ログイン画面(フォーム)
├── auth.php         # 認証処理(POST受信、SESSION設定)
├── db-09.php        # ログイン後のページ(会員専用ページ)
├── logout.php       # ログアウト処理
└── common.php       # 定数・共通関数

フローチャート

login.php (ログイン画面)

auth.php (認証処理:POST受信・SESSION設定)

db-09.php (ログイン後のページ:会員専用ページ)

logout.php (セッション情報の破棄)

login.php に戻る

完成イメージ

1.common.php(定数と共通処理)

まずは、ログインで使用するユーザー名とパスワードを定義し、共通で使う関数をまとめておきます。

<?php
// PHPでセッションを使うための「スタートボタン」
session_start();

// 管理者のログイン情報
define('ADMIN_USER', 'admin');
define('ADMIN_PASS', 'password123');

// HTML出力のためのエスケープ関数
function h($str)
{
    return htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
}

session_start() とは?

セッションを使うための「スタートボタン」です。ログイン機能の場合、「ログインしているかどうか」を覚えておき、どのページでも確認できるようになります。

  • セッションの仕組み
    • サーバー側に「セッション情報」という箱を作り、ユーザーごとのデータを一時的に保存します。
    • ユーザーのブラウザには「セッションID」という番号だけがクッキーで渡されます。
    • その番号を手がかりに、サーバーが「誰がどの状態か」を管理します。
  • 使い方のポイント
    • session_start(); は必ず ページの一番最初 に書きます。これがないと $_SESSION が使えません。
    • 一度ログインすると、その情報は 他のページにも引き継がれます
    • ログアウトすると、その箱の中身が消え、再びログインが必要になります。

イメージとしては「セッションは、ログイン状態を覚えておく箱」。
session_start(); は「その箱を開けて使えるようにするスイッチ」です。

define() 関数とは?

define('ADMIN_USER', 'admin');
define('ADMIN_PASS', 'password123');
  • 意味:「定数」を作る関数です。
  • 定数は一度設定すると変更できない値で、プログラムのどこからでも使えます。
  • define('名前', 値); という形で書きます。
  • ここでは ユーザー名パスワード を固定して使えるようにしています。
  • 例: echo ADMIN_USER; // admin と表示される
  • メリット:何度も同じ文字列を書く必要がなく、後からユーザー名やパスワードを変更するときに、この1か所を書き換えればOK。

セキュリティの注意点

common.php にはログイン用の ユーザー名やパスワード が書かれています。
そのため、安全のために ドキュメントルート(公開ディレクトリ)の外に置くことをおすすめします。

/var/www/public_html/login.php     ← 公開ディレクトリ(ブラウザから見える)
/var/www/config/common.php         ← 公開ディレクトリの外(直接アクセス不可)

やむを得ず同じディレクトリに置く場合

  • .htaccess などで直接アクセスを禁止しておく必要があります。

2.login.php(ログインフォーム)

<?php
require 'common.php';
$errors = $_SESSION['errors'] ?? [];
?>
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>ログイン</title>
</head>
<body>
    <h1>ログインページ</h1>

    <?php if (!empty($errors)): ?>
        <?php foreach ($errors as $error): ?>
            <p><?php echo h($error); ?></p>
        <?php endforeach; ?>
        <?php unset($_SESSION['errors']); // 一度表示したらセッションから削除 ?>
    <?php endif; ?>

    <form action="auth.php" method="post">
        <label>ユーザー名:<input type="text" name="username"></label><br>
        <label>パスワード:<input type="password" name="password"></label><br>
        <button type="submit">ログイン</button>
    </form>
</body>
</html>

どこでエラーを表示しているか?

<?php if (!empty($errors)): ?>
    <?php foreach ($errors as $error): ?>
        <p><?php echo h($error); ?></p>
    <?php endforeach; ?>
    <?php unset($_SESSION['errors']); ?>
<?php endif; ?>

  • $errors = $_SESSION['errors'] ?? [];
    • auth.php で保存したエラーメッセージをセッションから取り出して表示
  • !empty($errors)
    • → 配列 $errors の中身が空でなければ(つまり、何かしらエラーがあれば)表示
  • unset($_SESSION['errors']);
    • → 表示が終わったらセッションから削除(次にページを開いたときに二重表示されないようにする)

3.auth.php(認証処理)

<?php
require 'common.php';

$username = $_POST['username'] ?? '';
$password = $_POST['password'] ?? '';

$errors = []; // エラーメッセージを入れる配列

// --- バリデーション(空欄チェック) ---
if ($username === '') {
    $errors[] = 'ユーザー名を入力してください。';
}
if ($password === '') {
    $errors[] = 'パスワードを入力してください。';
}

// --- エラーがあればログインページに戻す ---
if (!empty($errors)) {
    $_SESSION['errors'] = $errors;
    header('Location: login.php');
    exit;
}

// --- 認証チェック ---
if ($username === ADMIN_USER && $password === ADMIN_PASS) {
    $_SESSION['logged_in'] = true;
    header('Location: db-09.php');
    exit;
} else {
    $_SESSION['errors'] = ['ユーザー名またはパスワードが違います。'];
    header('Location: login.php');
    exit;
}
  • $_SESSION['logged_in'] = true;
    → セッション変数 logged_in に「true」をセットします。
    → 「このユーザーはログイン済みですよ」というフラグを保存しているイメージ。
  • db-09.php など、ログインが必要なページでチェックできます

4.db-09.php(ログイン後ページ)

<?php
require 'common.php';

// ログインしていない場合は login.php に移動
// $_SESSION['logged_in'] が空(未定義)ならログインしていないと判断
if (empty($_SESSION['logged_in'])) {
    header('Location: login.php'); // login.php に移動
    exit; // ここで処理を終了(続きのHTMLは表示されない)
}

?>
<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <title>会員ページ</title>
</head>

<body>
    <h1>ログイン成功!</h1>
    <p>ここはログインした人だけが見られるページです。</p>
    <p><a href="logout.php">ログアウト</a></p>
</body>

</html>

5.logout.php(ログアウト処理)

<?php
require 'common.php';
$_SESSION = [];
session_destroy();
header('Location: login.php');
exit;

$_SESSION = [];

  • セッションに入っているデータを全部空にします。
  • $_SESSION は配列なので、[] を代入すると中身が全部消えます。

session_destroy();

  • セッションそのものを破棄します。
  • $_SESSION の中身を空にするだけでは、セッションIDが残ったままです。
  • session_destroy() を呼ぶことで、
    • サーバー側に保存してあるセッションデータを削除
    • セッションIDも無効化
      されます。