💡 今日の3行まとめ
- URLのクエリ文字列を
.で手動連結すると、空白や&記号でURLが途中で壊れる - 連想配列を
http_build_query()に渡せば、URLエンコードと&結合を自動で処理してくれる - 値が
nullのキーは自動で除外されるため、未指定の検索条件もスッキリ省ける
1. 今日のお題とゴール
検索フォームの条件(キーワード・カテゴリ・ページ番号)が入った連想配列から、次のページへ移動するための安全なURLとHTMLリンクを生成してみましょう。
- キーワードに含まれるスペースや
&を壊さずにURLエンコードする - 未指定(
null)のcategoryはURLパラメータから除外する - 生成したURLを
<a>タグのhref属性へ安全に出力する
// 期待する出力例
生成URL: /search?keyword=PHP+%26+MySQL&page=2
HTML出力: <a href="/search?keyword=PHP+%26+MySQL&page=2">2ページ目へ</a>
2. ❌ やりがちなNGコード vs ⭕ コピペで動く正解コード
❌ やりがちなNGコードBefore
<?php
$keyword = 'PHP & MySQL';
$category = null;
$page = 2;
// 文字列連結で直接つなぐと、キーワード内の「&」でパラメータが分断されてしまう
$url = "/search?keyword={$keyword}&category={$category}&page={$page}";
echo $url . PHP_EOL;
// 出力: /search?keyword=PHP & MySQL&category=&page=2
文字列連結でURLを組み立てると、キーワード内の & が「パラメータの区切り」と誤認されて検索ワードが途切れます。また、未指定の category= も空のままURLに残ってしまいます。
⭕ コピペで動く正解コード(PHP 8.3+)After
<?php
declare(strict_types=1);
// 検索条件の連想配列(未指定の項目は null にしておく)
$params = [
'keyword' => 'PHP & MySQL',
'category' => null,
'page' => 2,
];
// 1. 連想配列からURLエンコード済みのクエリ文字列を生成(nullの項目は自動除外)
$query = http_build_query($params);
// 2. クエリが空でないときだけ「?」を付けてベースURLと結合する
$url = '/search' . ($query !== '' ? '?' . $query : '');
// 3. HTMLのaタグに出力するときは htmlspecialchars で「&」をエスケープする
$safeUrl = htmlspecialchars($url, ENT_QUOTES, 'UTF-8');
echo "生成URL: {$url}" . PHP_EOL;
echo "HTML出力: <a href=\"{$safeUrl}\">2ページ目へ</a>" . PHP_EOL;
3. ここだけ押さえる!3つのポイント
1記号や日本語を自動でURLエンコードしてくれる
http_build_query() に連想配列を渡すだけで、値に含まれる & は %26 に、半角スペースは + に自動変換されます。日本語や記号が混ざる検索ワードでも、URLが壊れる心配がありません。
2値が null の項目は自動でスキップされる
配列の値が null のキーは、生成されるクエリ文字列から自動的に除外されます。面倒な if 文を書かなくても、指定された検索条件だけをスッキリ連結できます。
3HTMLのリンクに出すときは htmlspecialchars() を通す
クエリ文字列の区切り文字 & をHTMLの href 属性にそのまま書くと、HTMLの構文エラーやXSSの原因になります。画面の <a> タグに出力する直前に、必ず htmlspecialchars() で & に変換しましょう。
4. 1分ミニチャレンジ
🚀 手を動かしてみよう
正解コードの 'category' => null, の1行を 'category' => '',(空文字)に変えて実行してみましょう。
ヒント:空文字 '' は除外されず category=& として出力されるため、未入力の検索項目をURLから消したいときは null に揃えて渡すのがコツです!