そもそも「URL エンコード」とは何をしているのか
まず、ざっくりイメージからいきます。
"こんにちは PHP & URL"
→ "こんにちは PHP & URL" のまま URL に入れる
→ 文字化け・途中で切れる・パラメータが壊れる 可能性
→ "こんにちは%20PHP%20%26%20URL" のように
「URL 用に安全な文字列」に変換してから使う
URL には「そのまま使ってはいけない文字」や「特別な意味を持つ文字」があります。
スペース、日本語、&、?、# などが代表例です。
それらを「%E3%81…」のような %+16進数の形に変換して、
URL として安全に扱えるようにするのが「URL エンコード」です。
PHP では、この URL エンコードをしてくれる関数として主に次の2つがあります。
urlencoderawurlencode
この2つの違いと、実務でどう使い分けるかを、初心者向けにかみ砕いて整理していきます。
PHP の URL エンコードの基本:urlencode と rawurlencode
urlencode の特徴(フォーム用寄り)
urlencode は、古い仕様(application/x-www-form-urlencoded)に基づいたエンコードです。
ざっくり言うと、
- 英数字と
-_.はそのまま - それ以外は
%XX形式に変換 - スペースは
+に変換される
というルールで動きます。
$text = "PHP URL encode test 1 2 3";
echo urlencode($text);
// PHP+URL+encode+test+1+2+3
PHPスペースが + になっているのがポイントです。
これは「HTML フォームの送信形式」に合わせた仕様で、
クエリパラメータ(?q=... の右側)を作るときなどに使われてきました。
rawurlencode の特徴(RFC 3986 準拠)
rawurlencode は、RFC 3986 という現在の標準仕様に基づいたエンコードです。
- 英数字と
-_.~はそのまま - それ以外は
%XX形式に変換 - スペースは
%20に変換される
というルールで動きます。
$text = "PHP URL encode test 1 2 3";
echo rawurlencode($text);
// PHP%20URL%20encode%20test%201%202%203
PHPスペースが + ではなく %20 になっているのが、urlencode との一番大きな違いです。
どっちを使えばいいの?実務でのざっくり指針
原則:「迷ったら rawurlencode」で OK
実務的な結論から先に言うと、
迷ったら
rawurlencodeを使う
でほぼ困りません。
理由はシンプルで、
- RFC 3986 準拠で、今の Web の標準に沿っている
- スペースを
%20にするので、URL の各要素(パス・クエリ値など)を安全に扱いやすい - API や外部サービスとの連携でも、
rawurlencodeを前提にしている例が多い
からです。
ざっくり使い分けイメージ
初心者向けに、まずはこう覚えておくといいです。
- 「URL の一部(パス、クエリパラメータの値、ファイル名など)をエンコードしたい」
→rawurlencodeを使う - 「昔ながらのフォーム送信形式に合わせたい」「既存仕様が
+前提」
→ そのときだけurlencodeを検討
ほとんどの新規開発では、rawurlencode だけで十分です。
具体例で「URL エンコードの必要性」を体感する
例1:検索キーワードを URL に埋め込む
ユーザーが入力した検索キーワードを、https://example.com/search?q=キーワード のような URL にしたいケースを考えます。
$keyword = "iPhone & Galaxy / Note=100% #1";
PHPこれをそのまま URL に入れると、& や # のせいで「パラメータが途中で切れる」「ハッシュ扱いになる」など、
いろいろ壊れます。
rawurlencode を使うとこうなります。
$keyword = "iPhone & Galaxy/Note=100% #1";
$encoded = rawurlencode($keyword);
echo 'https://example.com/search?q=' . $encoded;
// https://example.com/search?q=iPhone%20%26%20Galaxy%2FNote%3D100%25%20%231
PHP& → %26、/ → %2F、= → %3D、% → %25、# → %23 に変換されているので、
URL として安全に扱えるようになります。
例2:日本語を含むパスを作る
$path = "資料/売上レポート 2025年版.pdf";
$encodedPath = rawurlencode($path);
echo 'https://example.com/files/' . $encodedPath;
// https://example.com/files/%E8%B3%87%E6%96%99%2F%E5%A3%B2%E4%B8%8A%E3%83%AC%E3%83%9D%E3%83%BC%E3%83%88%202025%E5%B9%B4%E7%89%88.pdf
PHP日本語やスペース、/ などがすべて %XX 形式に変換され、
URL として壊れない形になります。
実務ユーティリティとして関数にまとめる
クエリパラメータ用のユーティリティ
「クエリパラメータの値をエンコードする」という用途に絞った関数を作ると、
呼び出し側の意図が分かりやすくなります。
/**
* クエリパラメータの値を URL エンコードする(RFC 3986 準拠)
*/
function encodeQueryValue(string $value): string
{
return rawurlencode($value);
}
PHP使い方はこうです。
$keyword = $_GET['q'] ?? '';
// 検索リンクを生成
$url = 'https://example.com/search?q=' . encodeQueryValue($keyword);
echo $url;
PHP「ここではクエリの値をエンコードしているんだな」という意図が、
関数名から読み取れるのがポイントです。
パス要素(ファイル名など)用のユーティリティ
/**
* URL のパス要素(ファイル名など)をエンコードする
*/
function encodePathSegment(string $segment): string
{
return rawurlencode($segment);
}
PHP$filename = "売上レポート 2025年版.pdf";
$url = 'https://example.com/files/' . encodePathSegment($filename);
echo $url;
PHP「パスの一部分だけをエンコードする」という意図を、
関数名で表現しておくと、後から読んだときに迷いません。
重要ポイント:やってはいけないこと(深掘り)
1. URL 全体を丸ごとエンコードしない
初心者がやりがちなのがこれです。
$url = "https://example.com/search?q=テスト&lang=ja";
echo rawurlencode($url);
PHPこれは「URL 全体」をエンコードしてしまっているので、https:// や /、?、& まで全部 %XX になり、
もはや「URL として使えない文字列」になります。
URL エンコードは、
「URL の一部(パラメータの値、パスの一要素など)に対して行う」
のが正しい使い方です。
- ベース URL(
https://example.com/search)はそのまま ?や&などの区切り記号もそのまま- 右側の「値」だけをエンコードする
というイメージを、しっかり持っておいてください。
2. 二重エンコードしない
もう一つの落とし穴が「二重エンコード」です。
$value = "A&B";
$once = rawurlencode($value); // A%26B
$twice = rawurlencode($once); // A%2526B
echo $once; // A%26B
echo $twice; // A%2526B
PHP% 自体が再度 %25 にエンコードされてしまうので、
元に戻せなくなります。
「すでにエンコード済みの値」を、
もう一度エンコードしないように注意が必要です。
設計としては、
- 「どのタイミングでエンコードするか」を決めておく
- それ以外の場所では「生の値」を扱う
というルールをチーム内で共有しておくと安全です。
まとめ:今日からの「URL エンコード」ユーティリティ
押さえておきたいポイントをコンパクトにまとめます。
- URL エンコードは、「URL に入れると危ない文字」を
%XX形式に変換して、安全にする処理。 - PHP には
urlencodeとrawurlencodeがあるが、実務では「迷ったらrawurlencode」でほぼ OK。 rawurlencodeは RFC 3986 準拠で、スペースを%20にする現在の標準的なやり方。- URL 全体を丸ごとエンコードしてはいけない。「パラメータの値」「パスの一要素」など、部分に対して使う。
- 二重エンコードを避けるために、「どこでエンコードするか」をコード上で明確にしておく。
