PHPで_GET・_POSTを使ってフォームの値を受け取る方法

phpアイキャッチ PHP

こんにちは、かつコーチです。

前回はDateTimeクラスで日付・時刻を扱う方法を解説しました。

今回は、PHPでWebアプリケーションを作るうえで避けて通れない「フォームから送られてきた値を受け取る」方法を解説します。

お問い合わせフォーム、検索ボックス、ログインフォームなど、ユーザーが何かを入力して送信する機能のほとんどが、今回解説する $_GET$_POST の仕組みの上に成り立っています。

私が初めてこの2つを学んだときに一番混乱したのが、「どっちを使えばいいのか分からない」という点でした。

今回はその判断基準も含めて、しっかり整理していきます。

_GETと_POSTとは

スーパーグローバル変数という特別な存在

$_GET$_POST は、スーパーグローバル変数と呼ばれる特別な変数です。

自分で定義しなくても、PHPが自動的に用意してくれていて、どこからでも(関数の中からでも)呼び出せます。

これらの中には、ユーザーがフォームに入力した値や、URLに付与されたパラメータが、連想配列の形で自動的に格納されています。

$_GETの基本

$_GET は、URLの末尾に ?key=value の形で付けられたパラメータを受け取るための変数です。

https://example.com/search.php?keyword=PHP&page=2

このURLでアクセスされたとき、search.php の中では次のように値を取り出せます。

<?php
$keyword = $_GET["keyword"];
$page = $_GET["page"];

echo "検索キーワード: " . $keyword . "\n";
echo "ページ番号: " . $page . "\n";
// 検索キーワード: PHP
// ページ番号: 2

$_GET はURLにパラメータがそのまま表示されるのが特徴です。

検索結果ページのように、URLを見ただけで「何を検索した結果か」が分かるページとの相性がよく、ブックマークや共有もしやすくなります。

$_POSTの基本

$_POST は、HTMLの <form> タグの method="post" で送信された値を受け取るための変数です。

<form method="post" action="register.php">
    <input type="text" name="username">
    <input type="password" name="password">
    <button type="submit">登録</button>
</form>
<?php
// register.php
$username = $_POST["username"];
$password = $_POST["password"];

echo "ユーザー名: " . $username;

$_POST は値がURLに表示されない点が $_GET との大きな違いです。

_GETと_POSTの使い分け

判断基準は「データの性質」

「結局どっちを使えばいいの?」という疑問は、初心者の頃に誰もが一度は感じるところだと思います。

判断基準はシンプルで、送るデータの性質によって決まります。

観点$_GET$_POST
データの見え方URLに表示されるURLに表示されない
データ量の目安少なめ(URL長に制限あり)制限が緩い
用途の例検索、ページ番号、絞り込み条件ログイン、会員登録、パスワード変更
ブックマーク可能(同じ結果を再現できる)基本的に不向き

「URLに残っても問題ないデータ」は $_GET「見られたくない・毎回送信すべきデータ」は $_POST、という基準で選ぶと迷いにくいです。

パスワードのような機密情報を $_GET で送ってしまうと、URLの閲覧履歴やサーバーのアクセスログにパスワードがそのまま残ってしまう危険があります。

ログインフォームは必ず $_POST を使うようにしましょう。

つまずきやすいポイント:値が存在しないときのエラー

かつコーチが実際にハマったエラー

私がまだ駆け出しの頃、お問い合わせフォームを作っていて次のようなエラーに遭遇しました。

Warning: Undefined array key "email" in /var/www/html/contact.php on line 5

原因は単純で、フォームを送信せずに直接 contact.php のURLにアクセスしたとき、$_POST["email"] というキー自体が存在していなかったためです。

フォーム経由でアクセスすることしか想定していなかったため、こうした「値が存在しないパターン」への対策を忘れていました。

❌ Before:値の存在チェックをせずにいきなり使う

<?php
// contact.php
$name = $_POST["name"];
$email = $_POST["email"];
$message = $_POST["message"];

echo "お問い合わせありがとうございます、" . $name . "様";

フォームを経由せずアクセスされた場合や、フォーム側で name 属性を書き間違えていた場合、$_POST["name"] のキーが存在せず、警告(Warning)が発生します。

警告が出ても処理自体は止まりませんが、意図しない空文字が処理に紛れ込み、後続の処理でさらに別のエラーを引き起こす原因になります。

✅ After:isset() や null合体演算子で存在チェックをする

<?php
// contact.php
$name = $_POST["name"] ?? "";
$email = $_POST["email"] ?? "";
$message = $_POST["message"] ?? "";

if ($name === "" || $email === "" || $message === "") {
    echo "未入力の項目があります";
    exit;
}

echo "お問い合わせありがとうございます、" . $name . "様";

??(null合体演算子)を使うと、「左側の値が存在しない、またはnullの場合に右側の値を使う」という処理を1行で書けます。

$_POST["name"] ?? "" と書けば、キーが存在しなくても空文字が代入されるだけで、警告は発生しません。

さらに、その後の if 文で「必須項目が空でないか」をチェックすることで、不完全な送信をきちんとはじく処理になっています。

isset() を使って同じことを書くと、次のようになります。

<?php
if (isset($_POST["name"])) {
    $name = $_POST["name"];
} else {
    $name = "";
}

どちらでも同じ意味になりますが、?? の方が短く書けるので、実務では ?? を使うケースが多い印象です。

セキュリティの基本:入力値をそのまま信用しない

htmlspecialcharsでXSS対策をする

フォームから受け取った値は、外部から送られてきた、信用できないデータとして扱う必要があります。

もし受け取った値をそのまま画面に表示してしまうと、悪意のあるユーザーがHTMLタグやJavaScriptコードを入力欄に埋め込み、意図しないスクリプトを実行させる「XSS(クロスサイトスクリプティング)」という攻撃につながる恐れがあります。

❌ Before:受け取った値をそのまま表示する

<?php
$name = $_POST["name"] ?? "";
echo "こんにちは、" . $name . "さん";
// $nameに <script>alert('攻撃');</script> のような文字列が入っていると
// そのままスクリプトとして実行されてしまう可能性がある

✅ After:htmlspecialcharsで無害化してから表示する

<?php
$name = $_POST["name"] ?? "";
$safeName = htmlspecialchars($name, ENT_QUOTES, "UTF-8");
echo "こんにちは、" . $safeName . "さん";
// <script>タグなどが文字列としてそのまま表示され、実行されなくなる

htmlspecialchars() は、<> などのHTMLタグとして解釈される記号を、&lt;&gt; といった「見た目だけ同じ、実行されない文字」に変換してくれる関数です。

フォームから受け取った値を画面に表示するときは、必ず htmlspecialchars() を通す、これはPHPでフォームを扱うときの鉄則として覚えておいてください。

まとめ

この記事のポイント

  • $_GET はURLパラメータ、$_POST はフォーム送信の値を受け取るスーパーグローバル変数
  • 検索条件など「URLに残ってよいデータ」は $_GET、パスワードなど「見られたくないデータ」は $_POST を使う
  • 値が存在しない場合に備えて ??(null合体演算子)や isset() でチェックする
  • フォームの入力値は必ず htmlspecialchars() で無害化してから画面に表示し、XSS対策をする

次に読むべき記事

フォームの値を受け取れるようになったら、次は「ログイン状態を保持する」ためのセッションの仕組みを見ていきましょう。

→ 次の記事:PHPのセッション(session_start)でログイン状態を保持する方法

タイトルとURLをコピーしました