ログイン状態を `$_SESSION` で保つ
テクノロジ系 / session-cookie (session / cookie / login / CSRF)
ログイン状態を $_SESSION で保つ
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 スクリプトで連続擬似化できる
→ ドリルへ
考えてみよう
既定では正解・不正解の判定はしません。自分のペースで「答えを見る」を。採点してほしい場合だけ「採点してほしい」を押してください。
ドリル 01 — ログイン → マイページ表示
問題
$_SESSION を使って「ログイン → マイページ表示」を 1 スクリプトで擬似化してください。
- 標準入力 1 行目をログインフォームの送信 (例:
name=太郎) と見なし、$_POSTに展開する - 「ログイン処理」として
$_SESSION['user'] = ['name' => $_POST['name']]を実行する - 「マイページ」として
isset($_SESSION['user'])を判定し、"ようこそ、{name}さん"を出力する
このドリルの入力例 (tests/input.txt):
name=太郎
期待される出力:
ようこそ、太郎さん
採点
php scripts/grade.php topics/session-cookie/ch04-login-flow/drill/01-login/
ヒント
// 「リクエスト 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 で代用可)。
ドリル 02 — ログイン → ログアウト → 状態確認
問題
$_SESSION を使って「ログイン → ログアウト → マイページ再表示」を 1 スクリプトで擬似化してください。
- 標準入力 1 行目をログインフォームの送信 (
name=太郎) と見なす - 「ログイン処理」として
$_SESSION['user']に名前を格納 - 「ログアウト処理」として
$_SESSION = []+session_destroy()を実行 - ログアウト後にもう一度
session_start()を呼び、isset($_SESSION['user'])の判定結果に応じて"ログアウト済"を出力する
このドリルの入力例 (tests/input.txt):
name=太郎
期待される出力:
ログイン: 太郎 ログアウト済
採点
php scripts/grade.php topics/session-cookie/ch04-login-flow/drill/02-logout/
ヒント
// リクエスト 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