この内容は古いバージョンです。最新バージョンを表示するには、戻るボタンを押してください。
バージョン:4
ページ更新者:guest
更新日時:2026-06-11 07:07:02

タイトル: $_POST
SEOタイトル: PHP $_POST スーパーグローバル変数完全ガイド

この記事の要点
  • $_POST
    から送信されたデータが入る連想配列型のスーパーグローバル変数
  • $_POST["name"] でアクセス。未定義キーには isset() または ?? null で防御
  • XSS / SQL Injection / CSRF を必ず対策。htmlspecialchars / PDO Prepared / CSRF Token が三種の神器
  • JSON / multipart は $_POST に入らない場合がある → php://input$_FILES で取得
  • Laravel では $request->input("name")$request->validated() が定石

$_POST とは

PHP のスーパーグローバル変数の 1 つで、HTTP POST リクエストで送信された値が連想配列として格納されています。スーパーグローバルなので、関数の中でも global 宣言不要でアクセスできます。

HTML フォームと $_POST の対応



    
    
    
    
    
    

POST フォームの例

↑ HTML フォーム例(上記のような POST フォームを想定)。送信先 register.php での受け取り:

 string(4) "Taro"
  ["email"]    => string(13) "taro@test.com"
  ["password"] => string(8) "secret12"
  ["agree"]    => string(1) "1"
  ["role"]     => string(4) "user"
}
*/

$username = $_POST['username'];
$email    = $_POST['email'];

$_POST で取得した値の確認

↑ 受信側 PHP で $_POST の中身を確認したイメージ。var_dumpprint_r で連想配列の内容が見えます。

未定義キー対策

checkbox が未チェック / select が未選択だと、そのキー自体が $_POST存在しない。直接アクセスすると Warning:

// ❌ Warning: Undefined array key "agree"
$agree = $_POST['agree'];

// ✅ isset で防御
$agree = isset($_POST['agree']) ? $_POST['agree'] : '0';

// ✅ Null Coalescing (PHP 7+)
$agree = $_POST['agree'] ?? '0';

// ✅ filter_input
$agree = filter_input(INPUT_POST, 'agree', FILTER_VALIDATE_INT);

// 推奨: バリデーション関数にまとめる
function postInput(string $key, string $default = ''): string {
    return isset($_POST[$key]) ? trim((string)$_POST[$key]) : $default;
}
$username = postInput('username');

セキュリティ対策の三種の神器

1. XSS 対策(出力時)

$comment = $_POST['comment'] ?? '';

// ❌ XSS 脆弱
echo "

$comment

"; // $comment = "" だと実行される // ✅ htmlspecialchars で対策 echo '

' . htmlspecialchars($comment, ENT_QUOTES, 'UTF-8') . '

';

2. SQL Injection 対策

// ❌ SQL Injection 脆弱
$email = $_POST['email'];
$pdo->query("SELECT * FROM users WHERE email = '$email'");

// ✅ PDO Prepared Statement
$stmt = $pdo->prepare('SELECT * FROM users WHERE email = ?');
$stmt->execute([$_POST['email']]);
$user = $stmt->fetch(PDO::FETCH_ASSOC);

// ✅ 名前付きバインド
$stmt = $pdo->prepare('INSERT INTO users (name, email) VALUES (:n, :e)');
$stmt->execute([
    ':n' => $_POST['username'],
    ':e' => $_POST['email'],
]);

3. CSRF 対策

session_start();

// トークン生成(フォーム表示時)
if (empty($_SESSION['csrf_token'])) {
    $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
$token = $_SESSION['csrf_token'];

// HTML 側
// 

// 受信時に検証
if (!hash_equals($_SESSION['csrf_token'] ?? '', $_POST['_token'] ?? '')) {
    http_response_code(419);
    die('CSRF token mismatch');
}

$_POST に入らないケース

ケース取得方法
JSON ボディ(Content-Type: application/jsonjson_decode(file_get_contents("php://input"), true)
ファイルアップロード(multipart/form-data$_FILES
PUT / DELETE / PATCH リクエストphp://input から自前パース
カスタム Content-Typephp://input
post_max_size 超過空になる + warning。php.ini で post_max_size 拡大
// JSON 受信
$raw  = file_get_contents('php://input');
$data = json_decode($raw, true);
if (!is_array($data)) {
    http_response_code(400);
    die('Invalid JSON');
}
$username = $data['username'] ?? '';

// ファイルアップロード
if ($_FILES['avatar']['error'] === UPLOAD_ERR_OK) {
    move_uploaded_file(
        $_FILES['avatar']['tmp_name'],
        __DIR__ . '/uploads/' . basename($_FILES['avatar']['name'])
    );
}

$_POST vs $_GET vs $_REQUEST

変数取得元用途
$_GETURL クエリ文字列 (?key=val)検索・ページング・冪等な参照
$_POSTPOST ボディ (application/x-www-form-urlencoded)登録・更新・削除
$_REQUESTGET + POST + COOKIE 混合★ 非推奨。意図不明になる
$_FILESmultipart アップロードファイル受信
$_COOKIEクッキーセッション識別等
$_SERVERサーバ環境変数REMOTE_ADDR 等

filter_input でバリデーション

// 整数
$age = filter_input(INPUT_POST, 'age', FILTER_VALIDATE_INT, [
    'options' => ['min_range' => 0, 'max_range' => 150]
]);
if ($age === false) {
    die('年齢が不正');
}

// メール
$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
if ($email === false) {
    die('メール形式不正');
}

// URL
$url = filter_input(INPUT_POST, 'url', FILTER_VALIDATE_URL);

// 配列も一括フィルタ
$data = filter_input_array(INPUT_POST, [
    'name'  => FILTER_DEFAULT,
    'age'   => FILTER_VALIDATE_INT,
    'email' => FILTER_VALIDATE_EMAIL,
]);

Laravel での書き方

use Illuminate\Http\Request;

public function store(Request $request)
{
    // 個別取得
    $name = $request->input('name');
    $age  = $request->input('age', 0);      // デフォルト値

    // 一括取得
    $all = $request->all();
    $sub = $request->only(['name', 'email']);
    $exc = $request->except(['password']);

    // バリデーション
    $validated = $request->validate([
        'name'     => 'required|string|max:100',
        'email'    => 'required|email|unique:users',
        'password' => 'required|min:8|confirmed',
    ]);

    User::create($validated);
}

// FormRequest クラスでバリデーション分離(推奨)
class StoreUserRequest extends FormRequest {
    public function rules(): array {
        return [
            'name'  => 'required|string|max:100',
            'email' => 'required|email|unique:users',
        ];
    }
}

FAQ

Q: $_POST が空になる
A: enctype="multipart/form-data" でもキー名が一致していれば入ります。post_max_size 超過 / Content-Type 違い / php://input を既に読んだ後だと空になることも。

Q: 配列キーで送信したい
A: $_POST["items"]$_POST["user"]["name"] として受け取れます。

Q: 受信した値の型は?
A: 基本すべて文字列。数値も "123" として入る。型変換は自前で (int)$_POST["age"] 等。

Q: Magic Quotes でクォートに \ が付く
A: PHP 5.4 で廃止済み。古い環境なら stripslashes() で除去。