ch04 6章中 4章目

ch04 — ログイン状態を `$_SESSION` で保つ

スライドで見る

この章を AI と学ぶ

💬 AI に聞く質問例 3 件
  1. 「ch04 — ログイン状態を `$_SESSION` で保つ」のつまずきやすいポイントを、初学者向けに3つ教えてください

    ChatGPT Claude Gemini

  2. 「ch04 — ログイン状態を `$_SESSION` で保つ」について、自分の手で試せる練習問題を3つ出してください (難易度を上げながら)

    ChatGPT Claude Gemini

  3. 「ch04 — ログイン状態を `$_SESSION` で保つ」を学んだ後、次に学ぶと良いトピックは何ですか?理由も教えてください

    ChatGPT Claude Gemini

概要

Web アプリの ログイン はしくみだけ見ると驚くほどシンプル。「ユーザーがフォームから ID とパスワードを送る → サーバーで照合 → 合っていたら $_SESSION['user_id'] = 42 のように記録」これだけ。以降のリクエストは「$_SESSION['user_id'] があるか?」を見るだけでログイン判定。ログアウトは session_destroy()$_SESSION = []

ここで 絶対にやってはいけない のがパスワードを 平文で保存すること。DB に password = 'taro123' と入れるのは事故待ち。PHP 標準の password_hash($password, PASSWORD_DEFAULT) で必ずハッシュ化し、ログイン時は password_verify($input, $hash) で照合する。bcrypt / argon2 など現代的なアルゴリズムを PHP が自動で選ぶ神関数。

ログインは本来 2 リクエスト分の動き (フォーム送信 → セッション保存 → 別ページで確認) なので、ドリルでは 1 ファイル内で連続実行して擬似化する。ログイン直後の session_regenerate_id(true) (次の ch06 で深掘り) もここから仕込むのが定石。php -S で動かせば PHPSESSID Cookie が本物の Session ID として機能する様子を確認できる。

学習目標

  • 「ログイン」= $_SESSION にユーザー情報を入れる、と言える
  • 「ログアウト」= session_destroy() または $_SESSION = []、と言える
  • 「2 リクエスト分の動き」を 1 つの PHP で 連続実行 して擬似化できる

ドリル

no 内容
01 「ログイン → マイページ表示」を 1 スクリプトで擬似化
02 「ログイン → ログアウト → 状態確認」を 1 スクリプトで擬似化

本物のセッション動作で確認したい場合

cd topics/session-cookie/ch04-login-flow/drill/01-login/
php -S localhost:8000 answer.php

ブラウザで http://localhost:8000/?name=太郎 を開くと「ようこそ、太郎さん」が出る。 リロードすると Session が保たれて同じ表示。

解説スライド 全 7 枚

右の ボタン キー(またはスワイプ)で次のスライドに進めます。 下の「縦表示」を開くと全スライドを一気に読めます。

  1. ログイン状態を $_SESSION で保つ

    Lesson 13 / Chapter 4

  2. ログインとは

    ログインしている」を、コード上どう表現するか:

    <?php
    session_start();
    
    // ログイン処理
    $_SESSION['user'] = [
        'id'   => 42,
        'name' => '太郎',
    ];

    $_SESSION['user'] に値が入っていれば「ログイン中」、空なら「未ログイン」。

    ただそれだけ。「ログイン状態」という特別な型・関数があるわけではない。

  3. マイページ側の判定

    <?php
    session_start();
    
    // ログイン判定: Session に user が入っているか
    if (!isset($_SESSION['user'])) {
        echo "未ログインです\n";
        exit;
    }
    
    $user = $_SESSION['user'];
    echo "ようこそ、{$user['name']}さん\n";
    • isset($_SESSION['user']) で「ログイン中か」を判定
    • 未ログインなら早期 exit で弾く (Web ではリダイレクトに置き換える)
    • ログイン中なら $_SESSION['user'] から名前などを取り出して表示
  4. ログアウトとは

    <?php
    session_start();
    
    // 方法 A: $_SESSION を空にする
    $_SESSION = [];
    
    // 方法 B: Session 自体を破棄する (より確実)
    session_destroy();
    方法 効果
    $_SESSION = [] 連想配列を空に。Session ID は残る
    session_destroy() サーバー側の Session データを 完全に削除

    → 本番では両方やる + Cookie の PHPSESSID も setcookie(..., '', 0) で消すのが定番。

  5. 採点用: 2 リクエストを 1 スクリプトで擬似化

    本来 「ログイン」「マイページ」は 別リクエスト。CLI 採点は 1 プロセスしか動かないので、両方を 1 つのスクリプトで連続実行 する:

    <?php
    // (採点用スタブ ... session の擬似化)
    
    // === リクエスト 1: ログイン ===
    $_SESSION['user'] = ['name' => '太郎'];
    
    // === リクエスト 2: マイページ ===
    if (isset($_SESSION['user'])) {
        echo "ようこそ、{$_SESSION['user']['name']}さん\n";
    } else {
        echo "未ログイン\n";
    }

    これで「Session を介して 2 リクエスト間で状態が引き継がれる」流れを擬似的に体験できる。本物の Web では PHP が Cookie 経由で自動的にやってくれる。

  6. ログアウトの擬似化

    <?php
    // === リクエスト 1: ログイン ===
    $_SESSION['user'] = ['name' => '太郎'];
    
    // === リクエスト 2: ログアウト ===
    $_SESSION = [];
    session_destroy();
    
    // === リクエスト 3: もう一度マイページ ===
    @session_start();   // destroy 後は再 start が必要
    if (isset($_SESSION['user'])) {
        echo "ようこそ、{$_SESSION['user']['name']}さん\n";
    } else {
        echo "ログアウト済\n";
    }

    ログアウト後は $_SESSION が空になるので、マイページ側の isset チェックが false に倒れる。

  7. このチャプターでできるようになること

    ✅ ログイン = $_SESSION に user を入れる、と言える ✅ ログアウト = $_SESSION = [] + session_destroy()、と言える ✅ isset($_SESSION['user']) でログイン判定を書ける ✅ 「2 リクエスト分の動き」を 1 スクリプトで連続擬似化できる

    → ドリルへ

1 / 7
📜 スライドを全部一気に読む(縦表示)

Lesson 13 / Chapter 4


ログインとは

ログインしている」を、コード上どう表現するか:

<?php
session_start();

// ログイン処理
$_SESSION['user'] = [
    'id'   => 42,
    'name' => '太郎',
];

$_SESSION['user'] に値が入っていれば「ログイン中」、空なら「未ログイン」。

ただそれだけ。「ログイン状態」という特別な型・関数があるわけではない。


マイページ側の判定

<?php
session_start();

// ログイン判定: Session に user が入っているか
if (!isset($_SESSION['user'])) {
    echo "未ログインです\n";
    exit;
}

$user = $_SESSION['user'];
echo "ようこそ、{$user['name']}さん\n";
  • isset($_SESSION['user']) で「ログイン中か」を判定
  • 未ログインなら早期 exit で弾く (Web ではリダイレクトに置き換える)
  • ログイン中なら $_SESSION['user'] から名前などを取り出して表示

ログアウトとは

<?php
session_start();

// 方法 A: $_SESSION を空にする
$_SESSION = [];

// 方法 B: Session 自体を破棄する (より確実)
session_destroy();
方法 効果
$_SESSION = [] 連想配列を空に。Session ID は残る
session_destroy() サーバー側の Session データを 完全に削除

→ 本番では両方やる + Cookie の PHPSESSID も setcookie(..., '', 0) で消すのが定番。


採点用: 2 リクエストを 1 スクリプトで擬似化

本来 「ログイン」「マイページ」は 別リクエスト。CLI 採点は 1 プロセスしか動かないので、両方を 1 つのスクリプトで連続実行 する:

<?php
// (採点用スタブ ... session の擬似化)

// === リクエスト 1: ログイン ===
$_SESSION['user'] = ['name' => '太郎'];

// === リクエスト 2: マイページ ===
if (isset($_SESSION['user'])) {
    echo "ようこそ、{$_SESSION['user']['name']}さん\n";
} else {
    echo "未ログイン\n";
}

これで「Session を介して 2 リクエスト間で状態が引き継がれる」流れを擬似的に体験できる。本物の Web では PHP が Cookie 経由で自動的にやってくれる。


ログアウトの擬似化

<?php
// === リクエスト 1: ログイン ===
$_SESSION['user'] = ['name' => '太郎'];

// === リクエスト 2: ログアウト ===
$_SESSION = [];
session_destroy();

// === リクエスト 3: もう一度マイページ ===
@session_start();   // destroy 後は再 start が必要
if (isset($_SESSION['user'])) {
    echo "ようこそ、{$_SESSION['user']['name']}さん\n";
} else {
    echo "ログアウト済\n";
}

ログアウト後は $_SESSION が空になるので、マイページ側の isset チェックが false に倒れる。


このチャプターでできるようになること

✅ ログイン = $_SESSION に user を入れる、と言える ✅ ログアウト = $_SESSION = [] + session_destroy()、と言える ✅ isset($_SESSION['user']) でログイン判定を書ける ✅ 「2 リクエスト分の動き」を 1 スクリプトで連続擬似化できる

→ ドリルへ

この章で取り組む 演習問題の流れ (2ステップ)
  1. 01 ドリル 01 — ログイン → マイページ表示 README.md starter.php answer.php
  2. 02 ドリル 02 — ログイン → ログアウト → 状態確認 README.md starter.php answer.php

演習問題の詳細

この章の演習問題の内容を読めます。実際に手元で解くには教材リポジトリを clone してください。

ドリル 01 — ログイン → マイページ表示

問題

$_SESSION を使って「ログイン → マイページ表示」を 1 スクリプトで擬似化してください。

  • 標準入力 1 行目をログインフォームの送信 (例: name=太郎) と見なし、$_POST に展開する
  • 「ログイン処理」として $_SESSION['user'] = ['name' => $_POST['name']] を実行する
  • 「マイページ」として isset($_SESSION['user']) を判定し、"ようこそ、{name}さん" を出力する

このドリルの入力例 (tests/input.txt):

name=太郎

期待される出力:

ようこそ、太郎さん

ヒント

// 「リクエスト 1: ログインフォーム送信」
$line = trim(fgets(STDIN) ?: '');
parse_str($line, $_POST);
$_SESSION['user'] = ['name' => $_POST['name']];

// 「リクエスト 2: マイページ」
if (isset($_SESSION['user'])) {
    echo "ようこそ、{$_SESSION['user']['name']}さん\n";
} else {
    echo "未ログイン\n";
}

本物の Web で確認したい場合

cd topics/session-cookie/ch04-login-flow/drill/01-login/
php -S localhost:8000 answer.php

ブラウザで http://localhost:8000/?name=太郎 を開く (ドリルでは $_POST 想定だが、php -S 単独確認時は $_GET で代用可)。

🧪 ブラウザで試す

スライドのコードを写経して ▶ 実行、自分で書いて 📝 採点 で答え合わせ。初回のみ PHP ランタイム読込で数秒かかります。

PHP ランタイム未読込

          

        

ドリル 02 — ログイン → ログアウト → 状態確認

問題

$_SESSION を使って「ログイン → ログアウト → マイページ再表示」を 1 スクリプトで擬似化してください。

  • 標準入力 1 行目をログインフォームの送信 (name=太郎) と見なす
  • 「ログイン処理」として $_SESSION['user'] に名前を格納
  • 「ログアウト処理」として $_SESSION = [] + session_destroy() を実行
  • ログアウト後にもう一度 session_start() を呼び、isset($_SESSION['user']) の判定結果に応じて "ログアウト済" を出力する

このドリルの入力例 (tests/input.txt):

name=太郎

期待される出力:

ログイン: 太郎
ログアウト済

ヒント

// リクエスト 1: ログイン
parse_str(trim(fgets(STDIN) ?: ''), $_POST);
$_SESSION['user'] = ['name' => $_POST['name']];
echo "ログイン: {$_SESSION['user']['name']}\n";

// リクエスト 2: ログアウト
$_SESSION = [];
@session_destroy();

// リクエスト 3: 再アクセス
@session_start();
if (isset($_SESSION['user'])) {
    echo "ようこそ、{$_SESSION['user']['name']}さん\n";
} else {
    echo "ログアウト済\n";
}

本物の Web で確認したい場合

cd topics/session-cookie/ch04-login-flow/drill/02-logout/
php -S localhost:8000 answer.php

🧪 ブラウザで試す

スライドのコードを写経して ▶ 実行、自分で書いて 📝 採点 で答え合わせ。初回のみ PHP ランタイム読込で数秒かかります。

PHP ランタイム未読込

          

        

演習問題(2問)

  1. ドリル 01 — ログイン → マイページ表示

    README.md starter.php answer.php

  2. ドリル 02 — ログイン → ログアウト → 状態確認

    README.md starter.php answer.php

サイト内で問題文・雛形・解答例を確認できます。実際に手元で解くには教材リポジトリを clone してください。

完了にすると進捗に反映されます