PHPのURLパラメータとは、URLに付けられた値をPHP側で受け取り、ページの表示内容や処理を切り替えるための仕組みです。
たとえば、以下のようなURLがあります。
https://example.com/product.php?id=10
このURLでは、?id=10 の部分がURLパラメータです。
より正確には、? 以降の部分をクエリ文字列と呼び、その中に含まれる id=10 のような値をクエリパラメータと呼びます。
ただし、実務では「URLパラメータ」という言い方もよく使われます。
そのため、この記事ではわかりやすく「URLパラメータ」という表現を使いながら解説します。
PHPでは、このURLパラメータを使って、商品詳細ページ、記事詳細ページ、検索ページ、一覧ページのページネーション、絞り込み機能などを実装できます。
たとえば、以下のURLならIDが10の商品を表示できます。
product.php?id=10
一方、以下のURLならIDが25の商品を表示できます。
product.php?id=25
このように、URLパラメータを使うと、同じPHPファイルでも受け取った値によって表示内容を変えられます。
URLパラメータの基本構造
URLパラメータは、URLの末尾に ? を付けて記述します。
https://example.com/page.php?name=value
基本的な形は以下の通りです。
?キー=値
たとえば、以下のURLを見てみましょう。
https://example.com/detail.php?id=10
この場合、URLパラメータは以下のように分けられます。
キー:id
値:10
PHPでは、このキー名を使って値を取得します。
$_GET['id'];
URLパラメータは、ページに追加情報を渡すために使われます。
たとえば、商品ID、記事ID、検索キーワード、カテゴリ名、ページ番号などをURLに含めて、PHP側で処理できます。
複数のURLパラメータを渡す方法
URLパラメータは、1つだけでなく複数渡すこともできます。
複数のパラメータを指定する場合は、& でつなぎます。
https://example.com/search.php?keyword=php&category=programming&page=2
このURLには、以下の3つのパラメータがあります。
| キー | 値 |
|---|---|
| keyword | php |
| category | programming |
| page | 2 |
PHPでは、それぞれ次のように取得できます。
$keyword = $_GET['keyword'] ?? '';
$category = $_GET['category'] ?? '';
$page = $_GET['page'] ?? '1';
複数の条件をURLに含めることで、検索条件や絞り込み条件を保持したままページを表示できます。
たとえば、ECサイトで「カテゴリは靴」「色は黒」「2ページ目」といった条件をURLで管理する場合、以下のようなURLになります。
products.php?category=shoes&color=black&page=2
このように、複数のURLパラメータを組み合わせることで、より細かい条件に応じたページ表示ができます。
PHPでURLパラメータを取得する方法
PHPでURLパラメータを取得するには、$_GET を使います。
$_GET は、URLのクエリ文字列から渡された値を格納するスーパーグローバル変数です。
たとえば、以下のURLにアクセスしたとします。
https://example.com/detail.php?id=5
この場合、PHPでは次のように id の値を取得できます。
<?php
$id = $_GET['id'];
echo $id;
?>
出力結果は以下のようになります。
5
PHP側では、URLパラメータが以下のような連想配列として扱われるイメージです。
$_GET = [
'id' => '5'
];
そのため、id の値を取得したい場合は、$_GET['id'] と書きます。
ただし、実際のコードでは、URLパラメータが存在しない場合に備えて、次のように書く方が安全です。
$id = $_GET['id'] ?? '';
$_GETとは
$_GET は、PHPにあらかじめ用意されているスーパーグローバル変数です。
スーパーグローバル変数とは、関数の外でも中でも参照できる特別な変数のことです。
$_GET には、URLの ? 以降に含まれるクエリ文字列の値が格納されます。
たとえば、以下のURLにアクセスした場合を考えます。
https://example.com/search.php?q=php&page=2
PHP側では、以下のように値を取得できます。
<?php
$q = $_GET['q'] ?? '';
$page = $_GET['page'] ?? '1';
echo $q;
echo $page;
?>
このとき、$_GET の中身は以下のようなイメージです。
[
'q' => 'php',
'page' => '2'
]
なお、$_GET という名前ですが、必ずしもHTTPメソッドがGETの場合だけに使われるわけではありません。
POSTリクエストであっても、URLにクエリ文字列が付いていれば、その値は $_GET から取得できます。
たとえば、以下のようなURLにPOST送信した場合でも、
contact.php?ref=ad
PHPでは以下のように取得できます。
$ref = $_GET['ref'] ?? '';
つまり、$_GET は「GET送信用の値」というより、URLのクエリ文字列から渡された値を受け取るための変数と理解するとよいです。
URLパラメータが存在するか確認する方法
URLパラメータは、必ず存在するとは限りません。
たとえば、以下のようなPHPコードがあるとします。
$id = $_GET['id'];
このコードは、URLに id パラメータがある場合は問題なく動きます。
detail.php?id=10
しかし、以下のように id がないURLでアクセスされた場合は注意が必要です。
detail.php
存在しないキーをそのまま参照すると、警告が出る可能性があります。
そのため、URLパラメータを取得するときは、存在チェックを行うのが基本です。
isset()を使う方法
isset() を使うと、指定したパラメータが存在するか確認できます。
<?php
if (isset($_GET['id'])) {
$id = $_GET['id'];
echo $id;
} else {
echo 'IDが指定されていません';
}
?>
id が存在する場合はその値を使い、存在しない場合は別の処理を行えます。
ただし、毎回 isset() を書くとコードが長くなることがあります。
その場合は、次に紹介するNull合体演算子を使うと簡潔に書けます。
Null合体演算子を使う方法
PHP 7以降では、Null合体演算子 ?? を使う書き方がよく使われます。
<?php
$id = $_GET['id'] ?? null;
if ($id !== null) {
echo $id;
} else {
echo 'IDが指定されていません';
}
?>
この書き方では、$_GET['id'] が存在すればその値を代入し、存在しなければ null を代入します。
より短く書きたい場合は、以下のように初期値を設定することもできます。
$id = $_GET['id'] ?? '';
検索キーワードやカテゴリなど、未指定の場合に空文字で扱いたい値では、このような書き方が便利です。
ページ番号のように初期値が決まっている場合は、以下のように書けます。
$page = $_GET['page'] ?? '1';
このように、URLパラメータを取得するときは「存在しない場合にどう扱うか」をあらかじめ決めておくことが大切です。
URLパラメータは文字列として受け取られる
PHPでURLパラメータを取得すると、基本的に値は文字列として扱われます。
たとえば、以下のURLがあるとします。
detail.php?id=10
この場合、id は見た目上は数値の 10 ですが、PHPでは文字列の "10" として受け取られます。
$id = $_GET['id'] ?? '';
そのため、数値として扱いたい場合は、型変換やバリデーションが必要です。
$id = (int)($_GET['id'] ?? 0);
ただし、単純に (int) で変換するだけでは不十分な場合があります。
たとえば、以下のような値が渡された場合、
?id=abc
(int)'abc' は 0 になります。
また、以下のような値の場合、
?id=10abc
(int)'10abc' は 10 になります。
そのため、IDやページ番号のように正の整数だけを受け付けたい場合は、先に値の形式を確認することが大切です。
<?php
$id = $_GET['id'] ?? '';
if (!ctype_digit($id)) {
exit('正しいIDを指定してください');
}
$id = (int)$id;
echo 'IDは' . $id . 'です';
?>
ctype_digit() は、文字列がすべて数字で構成されているかを確認する関数です。
商品ID、記事ID、ページ番号など、正の整数だけを許可したい場合に便利です。
ただし、ctype_digit() は負の数や小数には向いていません。
たとえば、以下のような値は数字のみではないため、ctype_digit() では弾かれます。
-1
1.5
abc
負の数や小数も許可したい場合は、filter_var() や filter_input() など、別の検証方法を使います。
URLパラメータを使う主な場面
URLパラメータは、WebサイトやWebアプリケーションのさまざまな場面で使われます。
代表的な用途を見ていきましょう。
商品詳細ページ
ECサイトの商品詳細ページでは、商品IDをURLパラメータで渡して、表示する商品を切り替えることがあります。
product.php?id=100
PHP側では id を取得し、そのIDに対応する商品情報を表示します。
$id = $_GET['id'] ?? '';
実際には、取得した id が正しい数値か確認したうえで、データベースから商品情報を取得します。
$id = $_GET['id'] ?? '';
if (!ctype_digit($id)) {
exit('正しい商品IDを指定してください');
}
$id = (int)$id;
このように、URLパラメータを使うことで、1つのPHPファイルで複数の商品詳細ページを表示できます。
記事詳細ページ
ブログやメディアサイトでも、記事IDをURLパラメータで渡すことがあります。
article.php?id=25
この場合、PHPでは id を受け取り、該当する記事を表示します。
$articleId = $_GET['id'] ?? '';
記事詳細ページでは、存在しないIDが指定された場合の処理も重要です。
if (!ctype_digit($articleId)) {
exit('正しい記事IDを指定してください');
}
そのうえで、該当記事が見つからなければ「記事が見つかりません」と表示するようにします。
不正な値や存在しないIDが指定されたときの処理を用意しておくことで、ユーザーにも管理者にもわかりやすいページになります。
検索ページ
検索ページでは、検索キーワードをURLパラメータとして扱うことがよくあります。
search.php?keyword=php
PHPでは以下のように取得できます。
$keyword = $_GET['keyword'] ?? '';
検索フォームで method="get" を指定すると、入力内容がURLパラメータとして送信されます。
<form action="search.php" method="get">
<input type="text" name="keyword">
<button type="submit">検索</button>
</form>
検索ページでGET送信がよく使われる理由は、検索結果のURLを共有しやすいからです。
たとえば、以下のURLをコピーして共有すれば、他の人も同じ検索条件のページを開けます。
search.php?keyword=php
また、検索結果ページをブックマークしやすいというメリットもあります。
ページネーション
記事一覧や商品一覧では、現在のページ番号をURLパラメータで管理することがあります。
articles.php?page=2
PHPでは、page を取得して、表示するデータの範囲を切り替えます。
$page = $_GET['page'] ?? '1';
ページ番号は1以上の整数である必要があるため、以下のようにチェックすると安全です。
$page = $_GET['page'] ?? '1';
if (!ctype_digit($page) || (int)$page < 1) {
$page = 1;
} else {
$page = (int)$page;
}
不正な値が指定された場合は、エラーにするのではなく1ページ目に戻す実装もよく使われます。
たとえば、以下のような値が指定された場合です。
?page=0
?page=-1
?page=abc
このような値が来ても、ページ表示が崩れないようにしておくことが大切です。
絞り込み機能
カテゴリ、タグ、色、サイズ、価格帯などの絞り込み条件もURLパラメータで扱えます。
products.php?category=shoes&color=black&size=m
PHPでは、それぞれの値を取得して検索条件として使います。
$category = $_GET['category'] ?? '';
$color = $_GET['color'] ?? '';
$size = $_GET['size'] ?? '';
ただし、カテゴリや並び替え条件などは、許可された値だけを使うようにするのが安全です。
$sort = $_GET['sort'] ?? 'new';
$allowedSorts = ['new', 'price_asc', 'price_desc'];
if (!in_array($sort, $allowedSorts, true)) {
$sort = 'new';
}
このように、受け取った値をそのまま使わず、許可リストと照合することで、不正な値によるトラブルを防ぎやすくなります。
流入元やキャンペーンの判別
広告、メールマガジン、SNS投稿などでは、どこからアクセスされたかを判別するためにURLパラメータを使うことがあります。
https://example.com/lp.php?utm_source=google&utm_medium=cpc&utm_campaign=spring_sale
このような utm_source、utm_medium、utm_campaign などのパラメータは、アクセス解析や広告効果測定でよく使われます。
たとえば、以下のような意味を持たせることができます。
utm_source=google
これは、Googleからの流入であることを示します。
utm_medium=cpc
これは、クリック課金型の広告からの流入であることを示します。
このように、URLパラメータはページの表示内容を変えるだけでなく、集客施策や効果測定にも使われます。
フォームとURLパラメータの関係
HTMLフォームで method="get" を指定すると、入力内容がURLパラメータとして送信されます。
<form action="search.php" method="get">
<input type="text" name="keyword">
<button type="submit">検索</button>
</form>
このフォームで PHP 入門 と入力して送信すると、以下のようなURLになります。
search.php?keyword=PHP+%E5%85%A5%E9%96%80
PHP側では、以下のように値を取得できます。
$keyword = $_GET['keyword'] ?? '';
検索フォーム、絞り込みフォーム、並び替えフォームなどでは、GET送信がよく使われます。
理由は、条件をURLに残せるからです。
たとえば、検索結果ページのURLをコピーすれば、同じ検索結果を他の人に共有できます。
一方で、ログインフォームや問い合わせフォームのように、URLに表示したくない情報を扱う場合は、通常 method="post" を使います。
フォームの内容をURLに残したいのか、それともURLに表示したくないのかによって、GETとPOSTを使い分けることが大切です。
GETとPOSTの違い
PHPでフォームの値を受け取る方法には、主にGETとPOSTがあります。
URLパラメータとして送られる値は、基本的に $_GET で受け取ります。
一方、POSTで送信されたフォームの本文データは、$_POST で受け取ります。
GETの特徴
GETは、送信内容がURLのクエリ文字列として表示されます。
search.php?keyword=php
GETは、主に以下のような処理に向いています。
- 検索
- 絞り込み
- 並び替え
- ページネーション
- 表示条件の切り替え
GETのメリットは、URLを共有しやすいことです。
検索結果や絞り込み結果をブックマークしたり、他の人に送ったりできます。
一方で、URLに値が表示されるため、パスワードや個人情報などの重要な情報を送る用途には向いていません。
また、URLに含まれる情報はブラウザの履歴やサーバーのログなどに残る可能性があります。
そのため、見られて困る情報はURLパラメータに含めないようにしましょう。
POSTの特徴
POSTは、送信内容が主にリクエストボディに入ります。
URLにはフォームの入力内容が表示されません。
<form action="contact.php" method="post">
<input type="text" name="name">
<button type="submit">送信</button>
</form>
PHPでは、POSTされた値を以下のように取得します。
$name = $_POST['name'] ?? '';
POSTは、主に以下のような処理に使われます。
- ログイン
- 会員登録
- 問い合わせフォーム
- 購入処理
- データの登録・更新・削除
ただし、POSTで送れば完全に安全というわけではありません。
POSTの内容はURLに表示されにくいだけで、通信内容を保護するにはHTTPSが必要です。
また、POSTリクエストであっても、URLにクエリ文字列を付けることはできます。
contact.php?ref=ad
この場合、ref=ad は $_GET で取得し、フォーム本文の値は $_POST で取得します。
$ref = $_GET['ref'] ?? '';
$name = $_POST['name'] ?? '';
URLパラメータをHTMLに表示するときの注意点
URLパラメータは、ユーザーが自由に変更できます。
そのため、URLパラメータの値をそのままHTMLに出力してはいけません。
たとえば、以下のようなコードは避けるべきです。
<?php
$name = $_GET['name'] ?? '';
echo $name;
?>
このコードでは、URLに入力された値がそのまま画面に表示されます。
もし悪意のあるHTMLやJavaScriptが入力された場合、ページ上で意図しないスクリプトが実行される可能性があります。
このような攻撃を、クロスサイトスクリプティング、またはXSSと呼びます。
HTMLに値を出力するときは、htmlspecialchars() を使ってエスケープします。
<?php
$name = $_GET['name'] ?? '';
echo htmlspecialchars($name, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
?>
htmlspecialchars() を使うことで、HTMLとして解釈される可能性のある文字を安全に表示できます。
たとえば、< や > などの文字が、HTMLタグとして解釈されにくい形に変換されます。
HTML本文に表示する場合だけでなく、フォームの value 属性に入れる場合もエスケープが必要です。
<input type="text" name="keyword" value="<?= htmlspecialchars($keyword, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8') ?>">
URLパラメータを画面に表示するときは、基本的に必ずエスケープすると考えておきましょう。
ただし、JavaScript内やURL内に値を埋め込む場合は、HTMLエスケープだけでは不十分なことがあります。
出力する場所に応じて、適切なエスケープ方法を選ぶことが重要です。
URLパラメータをSQLで使うときの注意点
URLパラメータを使ってデータベース検索を行う場合は、SQLインジェクションに注意が必要です。
SQLインジェクションとは、外部から入力された値を悪用して、不正なSQLを実行させる攻撃です。
たとえば、以下のようなコードは危険です。
<?php
$id = $_GET['id'] ?? '';
$sql = "SELECT * FROM products WHERE id = $id";
?>
このように、URLパラメータをSQL文に直接埋め込むと、想定外のSQLを実行される可能性があります。
安全に処理するには、プリペアドステートメントを使います。
PDOを使う場合は、以下のように書きます。
<?php
$pdo = new PDO(
'mysql:host=localhost;dbname=test;charset=utf8mb4',
'user',
'password',
[
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
]
);
$id = $_GET['id'] ?? '';
if (!ctype_digit($id)) {
exit('正しいIDを指定してください');
}
$id = (int)$id;
$stmt = $pdo->prepare('SELECT * FROM products WHERE id = :id');
$stmt->bindValue(':id', $id, PDO::PARAM_INT);
$stmt->execute();
$product = $stmt->fetch();
?>
このコードでは、まず id が数字だけで構成されているかを確認しています。
そのうえで、PDOのプリペアドステートメントを使い、:id に値をバインドしています。
URLパラメータをデータベース処理に使う場合は、以下の流れを意識しましょう。
URLパラメータを取得する
期待する形式か検証する
必要に応じて型変換する
SQLには直接埋め込まず、プリペアドステートメントを使う
この流れを守ることで、SQLインジェクションのリスクを大きく減らせます。
URLパラメータを安全に扱う基本
URLパラメータは便利ですが、外部から送られてくる値であるため、そのまま信用してはいけません。
ユーザーはURLを自由に書き換えられます。
たとえば、通常は以下のようなURLを想定していたとしても、
detail.php?id=10
ユーザーは以下のように変更できます。
detail.php?id=9999
さらに、想定外の文字列を入れることもできます。
detail.php?id=abc
そのため、URLパラメータは常に「信用できない外部入力」として扱う必要があります。
入力値を信用しない
URLパラメータは、ユーザーが自由に変更できます。
画面上のリンクからアクセスした場合だけでなく、ブラウザのアドレスバーで直接書き換えることもできます。
そのため、URLパラメータを受け取ったら、まず「想定した値かどうか」を確認することが重要です。
「リンクから来る値だから大丈夫」と考えず、どのような値でも送られてくる可能性があると考えておきましょう。
バリデーションする
バリデーションとは、入力された値が期待する形式かどうか確認することです。
IDなら数字かどうか、ページ番号なら1以上の整数かどうか、カテゴリなら許可された値かどうかを確認します。
$page = $_GET['page'] ?? '1';
if (!ctype_digit($page) || (int)$page < 1) {
$page = 1;
} else {
$page = (int)$page;
}
並び替え条件のように、使える値が決まっている場合は、許可リストを使うと安全です。
$sort = $_GET['sort'] ?? 'new';
$allowedSorts = ['new', 'price_asc', 'price_desc'];
if (!in_array($sort, $allowedSorts, true)) {
$sort = 'new';
}
このように、受け取った値が想定内かどうか確認してから処理に使います。
出力時にエスケープする
URLパラメータをHTMLに表示するときは、htmlspecialchars() を使います。
$keyword = $_GET['keyword'] ?? '';
echo htmlspecialchars($keyword, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
入力時にバリデーションしていても、画面に表示するときはエスケープするのが基本です。
特に、検索キーワードや名前など、ユーザーが自由に入力できる値を表示する場合は注意しましょう。
SQLには直接埋め込まない
データベース検索に使う場合は、URLパラメータをSQL文に直接連結しないようにします。
危険な例は以下です。
$sql = "SELECT * FROM articles WHERE id = " . $_GET['id'];
安全に書くなら、プリペアドステートメントを使います。
$stmt = $pdo->prepare('SELECT * FROM articles WHERE id = :id');
$stmt->bindValue(':id', $id, PDO::PARAM_INT);
$stmt->execute();
URLパラメータをデータベースに使う場合は、バリデーションとプリペアドステートメントを組み合わせることが大切です。
URLエンコードとは
URLには、そのまま使えない文字があります。
たとえば、日本語、スペース、一部の記号などをURLに含める場合は、URLエンコードが必要です。
たとえば、検索キーワードとして「PHP 入門」を渡したい場合、URLでは以下のように変換されます。
search.php?keyword=PHP+%E5%85%A5%E9%96%80
または、スペースが %20 として表現されることもあります。
search.php?keyword=PHP%20%E5%85%A5%E9%96%80
このように、URLで安全に扱える形へ変換することをURLエンコードといいます。
PHPでURLパラメータを作成する場合は、urlencode()、rawurlencode()、http_build_query() などを使います。
$keyword = 'PHP 入門';
$url = 'search.php?keyword=' . urlencode($keyword);
echo $url;
出力例は以下です。
search.php?keyword=PHP+%E5%85%A5%E9%96%80
ただし、複数のURLパラメータを組み立てる場合は、手動で連結するよりも http_build_query() を使う方が便利です。
urlencode()とrawurlencode()の違い
PHPには、URLエンコード用の関数として urlencode() と rawurlencode() があります。
どちらもURLで扱える形に文字列を変換するための関数ですが、スペースの扱いなどに違いがあります。
urlencode()の特徴
urlencode() では、スペースが + に変換されます。
echo urlencode('PHP 入門');
出力例は以下です。
PHP+%E5%85%A5%E9%96%80
フォームのクエリ文字列を作る場合などで使われます。
たとえば、検索キーワードをURLパラメータに含める場合は、urlencode() を使ってエンコードできます。
rawurlencode()の特徴
rawurlencode() では、スペースが %20 に変換されます。
echo rawurlencode('PHP 入門');
出力例は以下です。
PHP%20%E5%85%A5%E9%96%80
rawurlencode() は、URLのパス部分に値を埋め込む場合などに使われることがあります。
ただし、パス全体にそのまま使うと / などもエンコードされる可能性があります。
実務では、パス全体ではなく、パスの各部分ごとにエンコードすることがあります。
たとえば、以下のようなURLを作りたい場合を考えます。
/articles/PHP 入門
この場合、パスの一部である PHP 入門 の部分だけをエンコードするイメージです。
$slug = 'PHP 入門';
$url = '/articles/' . rawurlencode($slug);
出力例は以下です。
/articles/PHP%20%E5%85%A5%E9%96%80
クエリ文字列を組み立てる場合は、基本的に http_build_query() を使うのがおすすめです。
PHPでURLパラメータ付きURLを作る方法
PHPでURLパラメータ付きのURLを作る場合、文字列を手動で連結することもできます。
$keyword = 'PHP 入門';
$url = 'search.php?keyword=' . urlencode($keyword);
ただし、パラメータが複数になると、手動で連結するのは面倒です。
$url = 'search.php?keyword=' . urlencode($keyword) . '&page=' . urlencode($page);
このような場合は、http_build_query() を使うと便利です。
$params = [
'keyword' => 'PHP 入門',
'page' => 2,
'category' => 'programming',
];
$url = 'search.php?' . http_build_query($params);
echo $url;
出力例は以下です。
search.php?keyword=PHP+%E5%85%A5%E9%96%80&page=2&category=programming
http_build_query() を使うと、配列からURLエンコード済みのクエリ文字列を作れます。
パラメータが増えても管理しやすいため、実務でもよく使われます。
既存の条件を維持してURLを作る例
検索結果ページで、検索キーワードを維持したままページ番号だけ変えたい場合があります。
たとえば、現在の検索条件が以下だとします。
$params = [
'keyword' => 'PHP',
'category' => 'programming',
'page' => 2,
];
次のページへのURLを作る場合は、page だけ変更します。
$params['page'] = 3;
$nextUrl = 'search.php?' . http_build_query($params);
HTMLに出力するときは、URLもエスケープします。
<a href="<?= htmlspecialchars($nextUrl, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8') ?>">次のページ</a>
このようにすると、検索キーワードやカテゴリなどの条件を維持したまま、ページ番号だけを変えられます。
URLパラメータで配列を渡す方法
PHPでは、URLパラメータで配列のような値を渡すこともできます。
たとえば、複数のカテゴリを選択する場合、以下のようなURLになります。
search.php?category[]=shoes&category[]=bag
PHPでは、次のように配列として受け取れます。
$categories = $_GET['category'] ?? [];
print_r($categories);
出力イメージは以下です。
Array
(
[0] => shoes
[1] => bag
)
チェックボックスで複数の値を送信する場合にも、この形式がよく使われます。
<form action="search.php" method="get">
<label>
<input type="checkbox" name="category[]" value="shoes">
靴
</label>
<label>
<input type="checkbox" name="category[]" value="bag">
バッグ
</label>
<button type="submit">検索</button>
</form>
PHP側では、以下のように受け取れます。
$categories = $_GET['category'] ?? [];
ただし、URLパラメータは自由に変更できるため、本当に配列として渡されているか確認する必要があります。
$categories = $_GET['category'] ?? [];
if (!is_array($categories)) {
$categories = [];
}
さらに、許可されたカテゴリだけを使うようにすると安全です。
$allowedCategories = ['shoes', 'bag', 'watch'];
$categories = $_GET['category'] ?? [];
if (!is_array($categories)) {
$categories = [];
}
$categories = array_values(array_intersect($categories, $allowedCategories));
このようにすることで、想定外の値が処理に使われるのを防げます。
URLパラメータとパスパラメータの違い
URLで値を渡す方法には、クエリパラメータだけでなく、パスに値を含める方法もあります。
クエリパラメータは以下のような形式です。
https://example.com/product.php?id=10
一方、パスに値を含める形式は以下のようになります。
https://example.com/products/10
このようなURLは、見た目がわかりやすく、ユーザーにも内容をイメージしてもらいやすい形式です。
たとえば、記事ページでは以下のようなURLにすることもあります。
https://example.com/articles/123
また、スラッグを使って以下のようなURLにすることもあります。
https://example.com/articles/php-url-parameter
PHPでこのようなURLを扱うには、ルーティングや .htaccess、Webサーバーの設定、フレームワークのルーターなどを使うことが多いです。
初心者の段階では、まず以下のようなクエリパラメータの扱いを理解するとよいです。
detail.php?id=10
そのうえで、ルーティングやパス設計を学ぶと、より実務的なURL設計ができるようになります。
実装例:商品詳細ページ
ここでは、URLパラメータで商品IDを受け取り、商品詳細を表示する簡単な例を紹介します。
URLは以下のような形です。
product.php?id=3
PHPコードは以下です。
<?php
$products = [
1 => ['name' => 'Tシャツ', 'price' => 3000],
2 => ['name' => 'スニーカー', 'price' => 8000],
3 => ['name' => 'バッグ', 'price' => 12000],
];
$id = $_GET['id'] ?? '';
if (!ctype_digit($id)) {
exit('正しい商品IDを指定してください');
}
$id = (int)$id;
if (!isset($products[$id])) {
exit('商品が見つかりません');
}
$product = $products[$id];
?>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>商品詳細</title>
</head>
<body>
<h1><?= htmlspecialchars($product['name'], ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8') ?></h1>
<p>価格:<?= htmlspecialchars((string)$product['price'], ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8') ?>円</p>
</body>
</html>
このコードでは、まず $_GET['id'] でURLパラメータを取得しています。
次に、ctype_digit() を使って、IDが数字だけで構成されているか確認しています。
その後、整数に変換し、該当する商品が存在するか確認しています。
最後に、商品名と価格をHTMLに出力しています。
出力時には htmlspecialchars() を使い、HTMLとして解釈される可能性のある文字を安全に処理しています。
実装例:検索ページ
検索ページでは、検索キーワードをURLパラメータで受け取ることが多いです。
URLは以下のようになります。
search.php?keyword=PHP
簡単なPHPコードは以下です。
<?php
$keyword = trim($_GET['keyword'] ?? '');
$articles = [
['title' => 'PHP入門'],
['title' => 'JavaScript入門'],
['title' => 'PHPでフォームを作る方法'],
];
$results = [];
if ($keyword !== '') {
foreach ($articles as $article) {
if (mb_stripos($article['title'], $keyword) !== false) {
$results[] = $article;
}
}
}
?>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>検索ページ</title>
</head>
<body>
<form action="search.php" method="get">
<input
type="text"
name="keyword"
value="<?= htmlspecialchars($keyword, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8') ?>"
>
<button type="submit">検索</button>
</form>
<?php if ($keyword !== ''): ?>
<h1>「<?= htmlspecialchars($keyword, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8') ?>」の検索結果</h1>
<?php if (!empty($results)): ?>
<ul>
<?php foreach ($results as $article): ?>
<li><?= htmlspecialchars($article['title'], ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8') ?></li>
<?php endforeach; ?>
</ul>
<?php else: ?>
<p>検索結果が見つかりませんでした。</p>
<?php endif; ?>
<?php endif; ?>
</body>
</html>
この例では、keyword パラメータを取得し、記事タイトルに含まれるかどうかを判定しています。
また、検索フォームの入力欄に検索キーワードを再表示しています。
このとき、value 属性に値を入れる前に htmlspecialchars() を使っています。
フォームの入力値として再表示する場合でも、URLパラメータ由来の値は必ずエスケープすることが重要です。
実装例:ページネーション
ページネーションでは、現在のページ番号をURLパラメータで管理できます。
articles.php?page=2
PHPでは以下のようにページ番号を取得します。
$page = $_GET['page'] ?? '1';
if (!ctype_digit($page) || (int)$page < 1) {
$page = 1;
} else {
$page = (int)$page;
}
このコードでは、page が存在しない場合は1ページ目として扱います。
また、page=0、page=-1、page=abc のような不正な値が指定された場合も、1ページ目に戻しています。
次のページへのリンクを作る場合は、http_build_query() を使うと便利です。
<?php
$keyword = $_GET['keyword'] ?? '';
$currentPage = $page;
$params = [
'keyword' => $keyword,
'page' => $currentPage + 1,
];
$nextUrl = 'articles.php?' . http_build_query($params);
?>
<a href="<?= htmlspecialchars($nextUrl, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8') ?>">次のページ</a>
このようにすると、検索キーワードを維持したまま、ページ番号だけを変更できます。
検索条件や絞り込み条件を保持したページネーションを作る場合に便利です。
filter_input()を使った取得方法
PHPでは、$_GET を直接使う代わりに、filter_input() を使って入力値を取得・検証することもできます。
たとえば、整数のIDを取得する場合は以下のように書けます。
<?php
$id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT);
if ($id === false || $id === null) {
echo '正しいIDを指定してください';
} else {
echo 'IDは' . $id . 'です';
}
?>
filter_input() を使うと、値の取得と検証をまとめて行えます。
ただし、IDとして0以下を許可したくない場合は、追加のチェックが必要です。
$id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT);
if ($id === false || $id === null || $id < 1) {
exit('正しいIDを指定してください');
}
filter_input() を使うか、$_GET と ctype_digit() を組み合わせるかは、プロジェクトや好みによって異なります。
重要なのは、外部から来た値をそのまま信用せず、必ず検証することです。
URLパラメータでよくあるミス
URLパラメータは簡単に使えますが、初心者がつまずきやすいポイントもあります。
よくあるミスを確認しておきましょう。
存在しないパラメータをそのまま使う
以下のようなコードは、id が存在しない場合に警告が出る可能性があります。
$id = $_GET['id'];
安全に書くなら、以下のようにします。
$id = $_GET['id'] ?? '';
または、存在するかどうかで処理を分けます。
if (isset($_GET['id'])) {
$id = $_GET['id'];
} else {
echo 'IDが指定されていません';
}
受け取った値をそのまま表示する
以下のようなコードは、XSSの原因になる可能性があります。
echo $_GET['keyword'];
安全に書くなら、以下のようにエスケープします。
echo htmlspecialchars($_GET['keyword'] ?? '', ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
URLパラメータをHTMLに表示する場合は、基本的に必ず htmlspecialchars() を使いましょう。
SQLに直接埋め込む
以下のようなコードは危険です。
$sql = "SELECT * FROM users WHERE id = " . $_GET['id'];
URLパラメータをSQLに直接連結すると、SQLインジェクションの原因になる可能性があります。
安全に書くなら、プリペアドステートメントを使います。
$stmt = $pdo->prepare('SELECT * FROM users WHERE id = :id');
$stmt->bindValue(':id', $id, PDO::PARAM_INT);
$stmt->execute();
数値チェックをしない
IDやページ番号は、見た目上は数値でも、URLからは任意の文字列が送られてきます。
そのため、数値として使う前にチェックが必要です。
$id = $_GET['id'] ?? '';
if (!ctype_digit($id)) {
exit('正しいIDを指定してください');
}
$id = (int)$id;
パラメータ名に扱いづらい文字を使う
PHPでは、外部から渡される変数名にドットやスペースが含まれると、扱いが変わることがあります。
そのため、URLパラメータ名には、英数字とアンダースコアを使うのが無難です。
使いやすい例は以下です。
user_name
keyword
page
category
sort
避けた方がよい例は以下です。
user.name
user name
実務では、シンプルで意味がわかりやすいパラメータ名を付けることが大切です。
URLパラメータを扱うときに便利な関数
PHPでURLパラメータを扱うときによく使う関数や構文をまとめると、以下のようになります。
| 関数・構文 | 用途 |
|---|---|
$_GET | URLパラメータを取得する |
isset() | パラメータが存在するか確認する |
?? | 存在しない場合の初期値を設定する |
trim() | 前後の空白を削除する |
ctype_digit() | 数字だけの文字列か確認する |
(int) | 整数に変換する |
htmlspecialchars() | HTML出力時にエスケープする |
urlencode() | URL用に文字列をエンコードする |
rawurlencode() | URL用に文字列をエンコードする |
http_build_query() | 配列からクエリ文字列を作る |
filter_input() | 入力値を取得・検証する |
filter_var() | 変数の値を検証・フィルタリングする |
in_array() | 許可された値か確認する |
これらを組み合わせることで、URLパラメータを安全かつ実用的に扱えます。
URLパラメータとサイト運用の関係
URLパラメータは、プログラム上の処理だけでなく、サイト運用にも関係します。
検索、絞り込み、並び替え、計測用パラメータなどを多用すると、似たようなURLが大量に生成されることがあります。
たとえば、以下のようなURLです。
/products.php?color=black
/products.php?size=m
/products.php?color=black&size=m
/products.php?size=m&color=black
これらのURLは、条件の組み合わせによって大量に増えることがあります。
特にECサイト、求人サイト、不動産サイト、記事検索サイトなど、絞り込み条件が多いサイトでは注意が必要です。
URLパラメータを増やしすぎると、管理が複雑になったり、同じような内容のページが複数できたりする可能性があります。
そのため、URLパラメータは「使えるから増やす」のではなく、目的に応じて整理しながら使うことが大切です。
計測用パラメータの場合
utm_source や utm_medium などの計測用パラメータは、基本的にページ内容を変えるものではありません。
たとえば、以下の2つのURLは、表示される内容が同じであることが多いです。
https://example.com/lp/
https://example.com/lp/?utm_source=google
このようなパラメータは、アクセス元やキャンペーンを判別するために使われます。
ページ内容を変えるためではなく、分析や効果測定のために使うものです。
そのため、計測用パラメータと表示内容を変えるパラメータは、役割を分けて考えると管理しやすくなります。
絞り込みパラメータの場合
一方、カテゴリや色、サイズなどの絞り込みパラメータは、ページ内容を変える場合があります。
/products.php?category=shoes
/products.php?category=shoes&color=black
このようなURLでは、指定された条件によって表示される商品一覧が変わります。
絞り込みパラメータを使う場合は、どの条件をURLに残すのか、どの条件を内部処理だけで扱うのかを整理しておくとよいです。
また、パラメータの順番が変わるだけで別のURLに見えることがあります。
/products.php?category=shoes&color=black
/products.php?color=black&category=shoes
この2つは、表示内容としては同じになることが多いですが、URLとしては異なります。
実務では、パラメータの順番をできるだけ統一すると管理しやすくなります。
URLパラメータを管理するときのポイント
URLパラメータをサイト運用で扱う場合は、以下の点を意識するとよいです。
- パラメータの役割を明確にする
- 計測用と表示切り替え用を分けて考える
- パラメータ名をわかりやすくする
- 同じ意味のパラメータを増やしすぎない
- パラメータの順番をできるだけ統一する
- 不要なパラメータ付きURLを内部リンクで増やしすぎない
- 表示内容がほぼ同じページを大量に作らない
- 管理しやすいURL設計にする
URLパラメータは便利ですが、設計せずに使い続けると、あとから整理が難しくなります。
特に、検索条件や絞り込み条件が多いサイトでは、早い段階でルールを決めておくと運用しやすくなります。
実務で使いやすいURLパラメータ取得の書き方
実務では、URLパラメータの種類に応じて取得方法を分けると安全です。
文字列、数値、ページ番号、許可リスト、配列など、値の種類ごとに処理を変えましょう。
文字列を取得する場合
検索キーワードなど、文字列として扱う値は以下のように取得できます。
$keyword = trim($_GET['keyword'] ?? '');
前後の空白を取り除きたい場合は、trim() を使います。
HTMLに出力するときは、必ずエスケープします。
echo htmlspecialchars($keyword, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
文字列は自由度が高い分、意図しない文字が含まれる可能性があります。
そのため、必要に応じて文字数制限を設けることもあります。
$keyword = mb_substr($keyword, 0, 100);
このようにすると、極端に長い文字列が送られてきた場合にも対応しやすくなります。
正の整数を取得する場合
商品IDや記事IDなど、正の整数だけを許可したい場合は、ctype_digit() を使うとわかりやすいです。
$id = $_GET['id'] ?? '';
if (!ctype_digit($id)) {
exit('正しいIDを指定してください');
}
$id = (int)$id;
ただし、0 を許可したくない場合は、整数化した後に1以上かどうかも確認します。
if ($id < 1) {
exit('正しいIDを指定してください');
}
IDとして 0 を使わない設計であれば、1以上かどうかを確認しておくと安心です。
ページ番号を取得する場合
ページ番号は、指定がなければ1ページ目として扱うことが多いです。
$page = $_GET['page'] ?? '1';
if (!ctype_digit($page) || (int)$page < 1) {
$page = 1;
} else {
$page = (int)$page;
}
ページ番号では、不正な値をエラーにするのではなく、1ページ目に戻す実装もよく使われます。
また、最大ページ数がわかっている場合は、上限を超えたページ番号にも対応できます。
$totalPages = 10;
if ($page > $totalPages) {
$page = $totalPages;
}
このようにしておくと、存在しないページ番号を指定された場合にも自然に処理できます。
許可された値だけ受け取る場合
並び替え条件やカテゴリなど、受け付ける値が決まっている場合は、許可リストを使います。
$sort = $_GET['sort'] ?? 'new';
$allowedSorts = ['new', 'price_asc', 'price_desc'];
if (!in_array($sort, $allowedSorts, true)) {
$sort = 'new';
}
この方法は、想定外の値を処理に使わないための基本的な対策です。
たとえば、並び替え条件をSQLの ORDER BY に使う場合、URLパラメータの値をそのままSQLに入れるのは危険です。
$allowedSorts = [
'new' => 'created_at DESC',
'price_asc' => 'price ASC',
'price_desc' => 'price DESC',
];
$sort = $_GET['sort'] ?? 'new';
$orderBy = $allowedSorts[$sort] ?? $allowedSorts['new'];
このように、URLパラメータの値を直接SQLに入れるのではなく、許可済みの値に変換して使うと安全です。
配列を取得する場合
チェックボックスなどで複数の値を受け取る場合は、配列かどうかを確認します。
$categories = $_GET['category'] ?? [];
if (!is_array($categories)) {
$categories = [];
}
さらに、許可された値だけを残すと安全です。
$allowedCategories = ['shoes', 'bag', 'watch'];
$categories = array_values(array_intersect($categories, $allowedCategories));
配列パラメータは便利ですが、想定外の形式で送られる可能性があります。
そのため、is_array() で確認し、必要に応じて許可リストで絞り込むことが大切です。
URLパラメータを扱う基本の流れ
URLパラメータを安全に扱うには、次の流れを意識するとわかりやすいです。
取得する → 検証する → 処理に使う → 出力時にエスケープする
たとえば、商品IDを受け取る場合は以下のようになります。
// 1. 取得する
$id = $_GET['id'] ?? '';
// 2. 検証する
if (!ctype_digit($id)) {
exit('正しいIDを指定してください');
}
// 3. 型変換する
$id = (int)$id;
// 4. 処理に使う
// データベース検索など
// 5. 出力時はエスケープする
この流れを守れば、URLパラメータを安全に扱いやすくなります。
特に重要なのは、URLパラメータを「外部から来た信用できない値」として扱うことです。
URLに表示されている値だからといって、安全な値とは限りません。
必ず確認してから処理に使い、画面に表示するときは適切にエスケープしましょう。
PHPのURLパラメータを理解するとできること
PHPのURLパラメータを理解すると、Webサイト制作でよく使う機能を実装しやすくなります。
たとえば、以下のような機能です。
- 商品詳細ページ
- 記事詳細ページ
- 検索機能
- 絞り込み機能
- 並び替え機能
- ページネーション
- 広告流入のトラッキング
- キャンペーンURLの管理
- 条件付きの一覧表示
- フォーム入力内容の保持
特に、検索機能や一覧ページを作る場合、URLパラメータの理解は欠かせません。
また、広告やメールマガジンなどの施策では、URLパラメータを使って流入元やキャンペーン名を判別することもあります。
つまり、URLパラメータはプログラム上の仕組みとしてだけでなく、サイト運用やアクセス解析にも関わる重要な要素です。
まとめ
PHPのURLパラメータとは、URLの ? 以降に付けられた値をPHP側で受け取り、ページの表示内容や処理を切り替えるための仕組みです。
たとえば、以下のようなURLでは、
detail.php?id=10
id=10 がURLパラメータです。
PHPでは、以下のように $_GET を使って値を取得できます。
$id = $_GET['id'] ?? '';
URLパラメータは、商品詳細ページ、記事詳細ページ、検索ページ、絞り込み、ページネーション、広告トラッキングなど、さまざまな場面で使われます。
ただし、URLパラメータはユーザーが自由に変更できるため、そのまま信用してはいけません。
安全に扱うためには、以下のポイントが重要です。
- 存在しないパラメータに備えて初期値を設定する
- 数値や文字列など、期待する形式か検証する
- HTMLに出力するときは
htmlspecialchars()でエスケープする - SQLに使うときはプリペアドステートメントを使う
- URLを組み立てるときは
http_build_query()を使う - 許可された値だけを使う場合は、許可リストでチェックする
- 計測用と表示切り替え用のパラメータを分けて管理する
PHPでURLパラメータを正しく扱えるようになると、動的なWebページを作る力が大きく伸びます。
まずは、$_GET で取得し、値を検証し、必要に応じてエスケープするという基本の流れを身につけることが大切です。
以上、PHPのURLパラメータについてでした。
最後までお読みいただき、ありがとうございました。









