タイトル: スーパーグローバル変数
SEOタイトル: PHP スーパーグローバル変数完全リファレンス
| この記事の要点 |
|
スーパーグローバル一覧と用途
| 変数 | 内容 | 主な用途 |
|---|---|---|
$GLOBALS | 全てのグローバル変数の連想配列 | 関数内からグローバル変数参照 |
$_SERVER | サーバ・実行環境情報 | URL / IP / UA / メソッド取得 |
$_GET | URL クエリ文字列 | 検索条件、ページ番号 |
$_POST | POST ボディ(form-urlencoded / multipart) | フォーム入力 |
$_REQUEST | GET / POST / COOKIE をマージ | 非推奨。明示の方が安全 |
$_COOKIE | クライアント送信の Cookie | セッション ID / ログイン状態 |
$_SESSION | セッション変数 | ログインユーザ情報 |
$_FILES | アップロードファイル | multipart/form-data |
$_ENV | 環境変数 | API キー、DB 接続情報 |
$_SERVER 主要キー
$_GET / $_POST: 外部入力のセキュリティ
外部入力は必ず: ① 存在チェック ② バリデーション ③ エスケープ。
prepare('SELECT * FROM users WHERE name LIKE ?');
$stmt->execute(['%' . $keyword . '%']);
$users = $stmt->fetchAll();
// ❌ NG: 文字列結合は致命的
$pdo->query("SELECT * FROM users WHERE name = '" . $_GET['q'] . "'");
// → q=' OR 1=1-- で全件取れる
$_REQUEST の罠
$_REQUEST は GET / POST / COOKIE をマージしたもの。同じキーがあるとどれが採用されるか不定になり、Cookie 経由で値を上書きされる脆弱性につながります:
$_SESSION
$_COOKIE と setcookie()
time() + 86400 * 30,
'path' => '/',
'domain' => '.example.com',
'secure' => true, // HTTPS のみ
'httponly' => true, // JS から読めない
'samesite' => 'Lax', // CSRF 対策
]);
// 削除(過去時刻にセット)
setcookie('theme', '', time() - 3600, '/');
$_ENV と環境変数
$GLOBALS
Laravel の Request クラスとの違い
Laravel では生のスーパーグローバルを直接触る必要はほぼありません:
input('id');
$id = $request->query('id'); // GET 限定
$id = $request->post('id'); // POST 限定
// ヘッダ・URL 等($_SERVER 相当)
$ua = $request->userAgent();
$ip = $request->ip();
$method = $request->method();
$url = $request->fullUrl();
// ファイル($_FILES 相当)
$file = $request->file('avatar');
// セッション($_SESSION 相当)
$request->session()->put('key', 'value');
session('key'); // ヘルパでも可
// Cookie($_COOKIE 相当)
$value = $request->cookie('name');
Cookie::queue('name', 'value', 60);
// 環境変数
$dbHost = config('database.connections.mysql.host'); // ★ env() でなく config()
}
セキュリティ・チェックリスト
| 対象 | リスク | 対策 |
|---|---|---|
| $_GET / $_POST を HTML 出力 | XSS | htmlspecialchars() |
| $_GET / $_POST を SQL に渡す | SQL Injection | prepared statement |
| $_GET / $_POST をシェル実行 | OS Command Injection | escapeshellarg() |
| $_FILES の type / name を信用 | RCE / 改ざん | サーバ側で再検証 |
| $_SERVER['PHP_SELF'] を直接出力 | XSS | SCRIPT_NAME を使う |
| $_SERVER['HTTP_X_FORWARDED_FOR'] | 偽装 | 信頼するプロキシのみで採用 |
| $_REQUEST を使う | 取得元不定 | $_GET / $_POST 明示 |
FAQ
Q: なぜスーパーグローバルと呼ぶ?
A: 関数内であっても global 宣言なしで参照できる「特別なグローバル」だからです。
Q: $_SESSION が空
A: session_start() 忘れか、Cookie 送信失敗、別ドメイン間で共有しようとしている等。session_status() で状態確認。
Q: $_POST が空で送れない
A: Content-Type が application/json なら $_POST には入りません(php://input + json_decode で読む)。