# $_SESSION とスーパーグローバル変数 解説
## 対象：社内Web開発初心者向け（PHP / HTML）

---

## 1. $_SESSION とは

**「ファイルを跨ぐグローバル変数」に近いイメージです。**
ただし通常のグローバル変数との重要な違いが1点あります。

```
通常の変数・グローバル変数  → 同じリクエスト（1回のページ読み込み）の中だけで生きる
$_SESSION                  → リクエストをまたいで、複数ページにわたって生き続ける
```

C# でいうと `Session["key"]` がそのまま対応します。

---

### セッションの仕組み（なぜページをまたいで保持できるか）

PHPはリクエストのたびに最初から実行されるため、変数は毎回消えます。
セッションは次の仕組みでその問題を解決します。

```
【ログイン時】
ブラウザ            PHP（login.php）          サーバー内（ファイル）
   |                      |                         |
   | ログイン送信 →       |                         |
   |                      | session_start()          |
   |                      | $_SESSION['user_name']   |
   |                      |   = '山田太郎'           |
   |                      | ─── セッションデータ保存 →| sess_abc123.txt
   |                      |     セッションID発行      |  { user_name: '山田太郎' }
   | ← クッキーでID送信   |                         |
   | PHPSESSID=abc123     |                         |

【次のページ（tokui_list.php）】
ブラウザ            PHP（tokui_list.php）     サーバー内（ファイル）
   |                      |                         |
   | クッキー付きで →     |                         |
   | PHPSESSID=abc123     | session_start()          |
   |                      | IDを元にデータ読み込み ← | sess_abc123.txt
   |                      | $_SESSION['user_name']   |
   |                      |   → '山田太郎' が入ってる|
```

```php
// auth.php 内（ログイン処理）
session_start();                           // セッション開始（必須）
$_SESSION['user_name']    = '山田太郎';   // 保存
$_SESSION['company_name'] = '株式会社〇〇';

// tokui_list.php 内（別ページ）
session_start();                           // セッション再開（必須）
echo $_SESSION['user_name'];               // → '山田太郎'（別ページでも取れる）
```

---

### $_SESSION の基本操作

```php
// 書き込み
$_SESSION['user_name'] = '山田太郎';

// 読み取り
$name = $_SESSION['user_name'];           // → '山田太郎'
$name = $_SESSION['user_name'] ?? '';     // キーが存在しない場合に備えて ?? を使う

// 削除（1件）
unset($_SESSION['user_name']);

// 全削除（ログアウト時）
session_destroy();
```

### $_SESSION の特性まとめ

| 項目 | 内容 |
|------|------|
| 保存場所 | **サーバー側**（デフォルトはサーバーのファイル） |
| 有効期間 | ブラウザを閉じるまで、またはタイムアウト（デフォルト24分） |
| 使用前 | `session_start()` が必須（今回は `requireLogin()` 内で呼ばれている） |
| 削除（1件） | `unset($_SESSION['key'])` |
| 削除（全件） | `session_destroy()`（ログアウト時） |

### 今回のコードでの使用箇所

```php
// tokui_list.php / tokui_edit.php のヘッダー部分
echo h($_SESSION['company_name']);  // → '株式会社〇〇'（ヘッダーに表示）
echo h($_SESSION['user_name']);     // → '山田太郎'（ヘッダーに表示）
```

---

## 2. スーパーグローバル変数 全体マップ

`$_XXXXX` 形式の変数は **スーパーグローバル** と呼ばれ、PHPが自動で用意します。
`global` 宣言なしにどのファイル・関数内でも使えます。

```
スーパーグローバル一覧
─────────────────────────────────────────────────────────────
保存場所              変数名           C# 相当
─────────────────────────────────────────────────────────────
URL（クエリ文字列）   $_GET            Request.QueryString
フォームPOST         $_POST           Request.Form
セッション（サーバー）$_SESSION        Session["key"]
クッキー（ブラウザ）  $_COOKIE         Request.Cookies / Response.Cookies
アップロードファイル  $_FILES          Request.Files
サーバー環境情報      $_SERVER         Request.ServerVariables / HttpContext
環境変数             $_ENV            Environment.GetEnvironmentVariable()
GET+POST+COOKIEまとめ $_REQUEST        （個別に取ること推奨・非推奨気味）
全グローバル変数      $GLOBALS         （使用非推奨）
─────────────────────────────────────────────────────────────
```

---

## 3. 各スーパーグローバルの詳細

### $_GET（今回のコードで使用）

URLのクエリ文字列（`?key=value`）を格納します。

```php
// URL例: tokui_list.php?tokui_manage=T001&searched=1

$_GET['tokui_manage']  // → 'T001'
$_GET['searched']      // → '1'
$_GET['存在しないキー'] // → 未定義エラー（必ず ?? で保護する）

// 安全な取り方（今回のコードはラッパー関数を使用）
$val = $_GET['tokui_manage'] ?? '';
$val = get_string('tokui_manage');    // ← 上記と同義（独自ラッパー）
```

---

### $_POST（今回のコードで使用）

フォームの `method="post"` で送信されたデータを格納します。

```php
// フォーム例:
// <input type="hidden" name="action" value="delete">

$_POST['action']                // → 'delete'
$_POST['target_tokui_manage']   // → 'T001'

// 安全な取り方
$val = $_POST['action'] ?? '';
$val = post_string('action');   // ← 独自ラッパー
```

---

### $_SESSION（今回のコードで使用）

ページをまたいでデータを保持します。詳細は「1. $_SESSIONとは」を参照。

```php
$_SESSION['user_name']     // → 'ログイン中のユーザー名'
$_SESSION['company_name']  // → '会社名'
```

---

### $_SERVER（今回のコードで使用）

サーバーおよびリクエストに関する情報を格納します。

```php
// 今回のコードで使ったもの
$_SERVER['REQUEST_METHOD']   // → 'GET' または 'POST'

// その他よく使うもの
$_SERVER['PHP_SELF']         // → '/master/tokui_list.php'（現在のファイルパス）
$_SERVER['HTTP_HOST']        // → 'localhost'（ホスト名）
$_SERVER['HTTPS']            // → 'on'（HTTPS接続時。HTTP時は未定義）
$_SERVER['REMOTE_ADDR']      // → '127.0.0.1'（接続元IPアドレス）
$_SERVER['HTTP_USER_AGENT']  // → 'Mozilla/5.0...'（ブラウザ情報）
$_SERVER['QUERY_STRING']     // → 'searched=1&tokui_manage=T001'（URLのクエリ文字列全体）
```

---

### $_COOKIE

ブラウザに保存されるデータです。「次回から自動ログイン」などに使います。

```php
// 書き込み（setcookie は HTML出力前に必須）
setcookie('remember_me', 'abc123', time() + (86400 * 30));
//                                  ↑ 30日後に期限切れ（秒単位）

// 読み取り
$token = $_COOKIE['remember_me'] ?? '';  // → 'abc123'

// 削除（有効期限を過去に設定する）
setcookie('remember_me', '', time() - 3600);
```

| 項目 | 内容 |
|------|------|
| 保存場所 | **ブラウザ側**（ユーザーのPC） |
| 有効期間 | 指定した日時まで（ブラウザを閉じても残る） |
| 用途 | 「次回から自動ログイン」など長期保持したい情報 |
| 注意 | ユーザーが改ざんできるため、機密情報は入れない |

#### セッションとクッキーの使い分け

```
機密情報（ユーザー名・権限・ログイン状態）  → $_SESSION（サーバー保管、安全）
長期保持・利便性向上（自動ログイントークン）  → $_COOKIE（ブラウザ保管、改ざん可能）
```

---

### $_FILES

ファイルアップロード時のデータを格納します。

```php
// HTML側（enctype 指定が必須）
// <form method="post" enctype="multipart/form-data">
//   <input type="file" name="upload_file">
// </form>

// PHP側
$file = $_FILES['upload_file'];

$file['name']     // → 'report.pdf'（元のファイル名）
$file['type']     // → 'application/pdf'（MIMEタイプ）
$file['size']     // → 204800（バイト数）
$file['tmp_name'] // → '/tmp/phpXXXXXX'（サーバーの一時保存パス）
$file['error']    // → 0（0が正常、それ以外はエラーコード）

// 一時ファイルを正式な場所に移動
if ($file['error'] === UPLOAD_ERR_OK) {
    move_uploaded_file($file['tmp_name'], '/uploads/' . basename($file['name']));
}
```

---

### $_REQUEST（非推奨気味）

`$_GET` + `$_POST` + `$_COOKIE` を全部まとめたものです。

```php
$value = $_REQUEST['tokui_manage'];
```

非推奨の理由：

```
・GETで来たのかPOSTで来たのか区別がつかなくなる
・意図しない値の上書きが起きる可能性がある（同名キーがあった場合）
→ $_GET / $_POST を明示的に使うほうが安全で読みやすい
```

---

## 4. 全体比較まとめ

```
               保存場所     有効期間              主な用途
──────────────────────────────────────────────────────────────────
$_GET          （なし）     1リクエストのみ       URL検索条件・ID受け渡し
$_POST         （なし）     1リクエストのみ       フォーム送信データ
$_SESSION      サーバー     ブラウザを閉じるまで  ログイン情報・一時データ
$_COOKIE       ブラウザ     指定日時まで          自動ログイン・設定保持
$_FILES        サーバー一時 1リクエストのみ       アップロードファイル
$_SERVER       （なし）     1リクエストのみ       サーバー・リクエスト情報
$_ENV          （なし）     プロセス存続中        環境変数（DB接続情報等）
$_REQUEST      （なし）     1リクエストのみ       非推奨（$_GET/$_POST を使う）
──────────────────────────────────────────────────────────────────
```

---

## 5. セキュリティ上の注意点

スーパーグローバルの値は**すべてユーザーが操作できる**ものと考えて扱います。

| 変数 | リスク | 対策 |
|------|--------|------|
| `$_GET` / `$_POST` | SQLインジェクション | `bindValue()` でパラメータ化 |
| `$_GET` / `$_POST` | XSS | `h()`（`htmlspecialchars()`）でエスケープ |
| `$_COOKIE` | 改ざん | 機密情報を入れない。トークンのみ保存 |
| `$_FILES` | 不正ファイルアップロード | 拡張子・MIMEタイプ・サイズを検証 |
| `$_SESSION` | セッション固定化攻撃 | ログイン後に `session_regenerate_id(true)` を呼ぶ |

```php
// セッション固定化攻撃への対策（ログイン成功直後に必ず呼ぶ）
session_regenerate_id(true);  // セッションIDを新しく発行し直す
```
