17.

PHP スーパーグローバル変数完全リファレンス

編集
この記事の要点
  • スーパーグローバルはスコープを越えてどこからでも参照可能な PHP 組込配列
  • 一覧: $GLOBALS / $_SERVER / $_GET / $_POST / $_REQUEST / $_COOKIE / $_SESSION / $_FILES / $_ENV
  • 外部入力($_GET/$_POST/$_REQUEST/$_COOKIE)は必ずバリデーション + エスケープ
  • $_REQUEST は GET / POST / COOKIE が混在する → 明示的に区別する方が安全
  • Laravel では基本 Illuminate\Http\Request を経由(DI 注入 + バリデーション)

スーパーグローバル一覧と用途

変数内容主な用途
$GLOBALS全てのグローバル変数の連想配列関数内からグローバル変数参照
$_SERVERサーバ・実行環境情報URL / IP / UA / メソッド取得
$_GETURL クエリ文字列検索条件、ページ番号
$_POSTPOST ボディ(form-urlencoded / multipart)フォーム入力
$_REQUESTGET / POST / COOKIE をマージ非推奨。明示の方が安全
$_COOKIEクライアント送信の Cookieセッション ID / ログイン状態
$_SESSIONセッション変数ログインユーザ情報
$_FILESアップロードファイルmultipart/form-data
$_ENV環境変数API キー、DB 接続情報

$_SERVER 主要キー

<?php
$_SERVER['REQUEST_METHOD'];     // GET / POST / PUT ...
$_SERVER['REQUEST_URI'];        // /users/1?tab=info
$_SERVER['QUERY_STRING'];       // tab=info
$_SERVER['HTTP_HOST'];          // example.com
$_SERVER['HTTPS'];              // 'on' なら HTTPS
$_SERVER['SERVER_NAME'];        // example.com
$_SERVER['SERVER_PORT'];        // 80 / 443
$_SERVER['REMOTE_ADDR'];        // クライアント IP(プロキシ越しなら X-Forwarded-For 見る)
$_SERVER['HTTP_USER_AGENT'];    // ブラウザ情報
$_SERVER['HTTP_REFERER'];       // 直前のページ
$_SERVER['HTTP_ACCEPT_LANGUAGE']; // ja,en-US;q=0.7
$_SERVER['SCRIPT_NAME'];        // /index.php
$_SERVER['PHP_SELF'];           // /index.php/foo(注意: XSS の温床)
$_SERVER['DOCUMENT_ROOT'];      // /var/www/html
$_SERVER['CONTENT_TYPE'];       // application/json
$_SERVER['CONTENT_LENGTH'];     // バイト数

// プロキシ / LB 越しの実 IP 取得(信用するヘッダはサーバ設定で決める)
function clientIp(): string {
    return $_SERVER['HTTP_X_FORWARDED_FOR']
        ?? $_SERVER['HTTP_X_REAL_IP']
        ?? $_SERVER['REMOTE_ADDR']
        ?? 'unknown';
}

$_GET / $_POST: 外部入力のセキュリティ

外部入力は必ず: ① 存在チェック ② バリデーション ③ エスケープ。

<?php
// ✅ Null 合体演算子で安全に取得
$page = (int) ($_GET['page'] ?? 1);
$keyword = trim((string) ($_GET['q'] ?? ''));

// XSS 対策: HTML 出力時にエスケープ
echo '検索: ' . htmlspecialchars($keyword, ENT_QUOTES | ENT_HTML5, 'UTF-8');

// SQL Injection 対策: prepared statement(必須)
$stmt = $pdo->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 経由で値を上書きされる脆弱性につながります:

<?php
// ❌ 推奨されない
$id = $_REQUEST['id'];   // GET? POST? COOKIE? 不明

// ✅ 明示的に取得元を限定
$id = $_GET['id'] ?? null;       // URL 経由
$id = $_POST['id'] ?? null;      // フォーム経由

// php.ini で挙動制御(request_order)
// request_order = "GP"  ← G:GET, P:POST, C:COOKIE

$_SESSION

<?php
session_start();              // 必ず先に呼ぶ(ヘッダ送信前)

// 値を保存
$_SESSION['user_id'] = 123;
$_SESSION['cart'] = ['p1', 'p2'];

// 取得
$userId = $_SESSION['user_id'] ?? null;

// 削除
unset($_SESSION['cart']);

// セッション破棄(ログアウト)
$_SESSION = [];
if (ini_get('session.use_cookies')) {
    $p = session_get_cookie_params();
    setcookie(session_name(), '', time() - 42000,
        $p['path'], $p['domain'], $p['secure'], $p['httponly']);
}
session_destroy();

// セッション固定化対策(ログイン直後)
session_regenerate_id(true);

$_COOKIE と setcookie()

<?php
// 取得
$theme = $_COOKIE['theme'] ?? 'light';

// セット(ヘッダ送信前である必要あり)
setcookie('theme', 'dark', [
    'expires'  => time() + 86400 * 30,
    'path'     => '/',
    'domain'   => '.example.com',
    'secure'   => true,         // HTTPS のみ
    'httponly' => true,         // JS から読めない
    'samesite' => 'Lax',        // CSRF 対策
]);

// 削除(過去時刻にセット)
setcookie('theme', '', time() - 3600, '/');

$_ENV と環境変数

<?php
// $_ENV は php.ini の variables_order に E が含まれる必要あり
// variables_order = "EGPCS"

$dbHost = $_ENV['DB_HOST'] ?? 'localhost';

// getenv() でも取得可能
$dbHost = getenv('DB_HOST');

// putenv() で実行時設定
putenv('DEBUG=1');

// .env ファイル運用は phpdotenv / Symfony Dotenv を使うのが定石
// Laravel: env('DB_HOST') / config('database.connections.mysql.host')

$GLOBALS

<?php
$counter = 0;

function inc(): void {
    // global $counter; と書く代わりに
    $GLOBALS['counter']++;
}

inc(); inc(); inc();
echo $counter;  // 3

// ★ アンチパターン: グローバル変数依存は避ける(テスト困難)
// → 引数や DI で渡す設計が望ましい

Laravel の Request クラスとの違い

Laravel では生のスーパーグローバルを直接触る必要はほぼありません:

<?php
use Illuminate\Http\Request;

public function show(Request $request)
{
    // GET / POST 一括取得(PHP の $_GET/$_POST 相当)
    $id = $request->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 出力XSShtmlspecialchars()
$_GET / $_POST を SQL に渡すSQL Injectionprepared statement
$_GET / $_POST をシェル実行OS Command Injectionescapeshellarg()
$_FILES の type / name を信用RCE / 改ざんサーバ側で再検証
$_SERVER['PHP_SELF'] を直接出力XSSSCRIPT_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-Typeapplication/json なら $_POST には入りません(php://input + json_decode で読む)。

編集
Post Share
子ページ
  1. $_SERVER
  2. $_GET
  3. $_POST
  4. $_ENV (PHP スーパーグローバル変数)
  5. $_COOKIE
  6. $_SERVER
  7. $_FILES
同階層のページ
  1. 基本事項
  2. HTMLへの埋め込み
  3. 変数
  4. 可変変数
  5. 定数
  6. データ型
  7. キャスト
  8. エスケープ文字
  9. 配列
  10. 演算子
  11. 代入の際の注意点
  12. 条件分岐
  13. 繰り返し処理
  14. クラスとインスタンス
  15. コンストラクタ
  16. 関数
  17. スーパーグローバル変数
  18. スコープ
  19. staticについて
  20. yieldについて
  21. ファイルのアップロード方法
  22. DB接続方法
  23. SQL実行方法
  24. カプセル化の具体例
  25. 継承の構文
  26. オーバーライド
  27. ポリモーフィズム(多様性)の具体例
  28. 抽象クラス・メソッドの構文と具体例
  29. GET通信
  30. try catchで全てのエラーを拾う方法

最近更新/作成されたページ