PHPで現在のURLを取得したい場合は、主に $_SERVER というスーパーグローバル変数を使います。
ただし、「現在のURLを取得する」といっても、実際には取得したい内容によってコードが少し変わります。
たとえば、以下のような違いがあります。
| 取得したい内容 | 例 |
|---|---|
| パスとクエリ文字列 | /blog/article.php?id=123 |
| 完全なURL | https://example.com/blog/article.php?id=123 |
| クエリ文字列なしのURL | https://example.com/blog/article.php |
| クエリ文字列のみ | id=123 |
| 現在のディレクトリURL | https://example.com/blog/ |
この記事では、PHPで現在のURLを取得する基本的な方法から、実務で注意したいセキュリティ面、WordPressでの取得方法まで詳しく解説します。
現在のURLを取得する基本コード
まず、現在アクセスしているページの完全なURLを取得する基本コードは以下です。
<?php
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
$host = $_SERVER['HTTP_HOST'];
$requestUri = $_SERVER['REQUEST_URI'];
$currentUrl = $protocol . '://' . $host . $requestUri;
echo $currentUrl;
たとえば、現在アクセスしているURLが以下だったとします。
https://example.com/blog/article.php?id=123&page=2
この場合、 $currentUrl には次のような文字列が入ります。
https://example.com/blog/article.php?id=123&page=2
基本的には、以下の3つを組み合わせて現在のURLを作ります。
$protocol // http または https
$host // example.com
$requestUri // /blog/article.php?id=123
つまり、現在URLは次のように組み立てられます。
$protocol . '://' . $host . $requestUri
$_SERVER['REQUEST_URI']でパスとクエリ文字列を取得する
REQUEST_URIとは
$_SERVER['REQUEST_URI'] は、現在リクエストされているURIを取得するための値です。
簡単にいうと、ドメイン名を除いたURLの後半部分を取得できます。
<?php
echo $_SERVER['REQUEST_URI'];
たとえば、以下のURLにアクセスしている場合、
https://example.com/blog/article.php?id=123
出力結果は次のようになります。
/blog/article.php?id=123
この中には、パスとクエリ文字列が含まれています。
/blog/article.php?id=123
分解すると、次のようになります。
| 部分 | 内容 |
|---|---|
| パス | /blog/article.php |
| クエリ文字列 | ?id=123 |
そのため、ドメイン名なしで現在のURL情報を取得したい場合は、$_SERVER['REQUEST_URI'] だけで十分です。
REQUEST_URIの使用例
現在のパスとクエリ文字列を表示したい場合は、次のように書けます。
<?php
$currentPath = $_SERVER['REQUEST_URI'] ?? '/';
echo $currentPath;
?? '/' を使っているのは、万が一 REQUEST_URI が存在しない場合に / を代入するためです。
通常のWebサーバー環境では REQUEST_URI が使えるケースが多いですが、サーバー環境によっては必ず存在するとは限りません。
実務では、このようにデフォルト値を用意しておくと安心です。
$_SERVER['HTTP_HOST']でホスト名を取得する
HTTP_HOSTとは
$_SERVER['HTTP_HOST'] を使うと、現在アクセスされているホスト名を取得できます。
<?php
echo $_SERVER['HTTP_HOST'];
たとえば、以下のURLにアクセスしている場合、
https://example.com/blog/article.php?id=123
出力結果は次のようになります。
example.com
ローカル環境でポート番号付きのURLにアクセスしている場合は、次のような値になることもあります。
localhost:8000
そのため、HTTP_HOST を使うと、ドメイン名やポート番号を含めたホスト情報を取得できます。
HTTP_HOSTを使うときの注意点
HTTP_HOST は便利ですが、実務では注意が必要です。
なぜなら、HTTP_HOST はHTTPリクエストの Host ヘッダーに由来する値だからです。
つまり、ユーザー側から送られるリクエスト内容の影響を受ける可能性があります。
そのため、以下のような用途では、HTTP_HOST をそのまま信頼しないほうが安全です。
- パスワードリセット用URLの生成
- メール本文に含めるURLの生成
- ログイン後のリダイレクトURL生成
- canonical URLの生成
- OGP URLの生成
- 決済後の戻りURL生成
通常の画面表示や簡易的なリンク生成では使われることが多いですが、セキュリティ上重要な処理では、許可されたホスト名だけを使うようにしましょう。
<?php
$allowedHosts = ['example.com', 'www.example.com'];
$host = $_SERVER['HTTP_HOST'] ?? 'example.com';
if (!in_array($host, $allowedHosts, true)) {
$host = 'example.com';
}
本番サイトのドメインが決まっている場合は、HTTP_HOST から取得するのではなく、設定ファイルや環境変数に固定のURLを持たせる方法もあります。
<?php
$baseUrl = 'https://example.com';
または、
<?php
$baseUrl = $_ENV['APP_URL'] ?? 'https://example.com';
httpとhttpsを判定する方法
$_SERVER['HTTPS']で判定する
現在のURLを完全な形で取得するには、URLの先頭が http:// なのか https:// なのかを判定する必要があります。
よく使われるのが、$_SERVER['HTTPS'] を確認する方法です。
<?php
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
このコードでは、$_SERVER['HTTPS'] が空でなく、かつ 'off' でなければ https と判定します。
<?php
if (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') {
$protocol = 'https';
} else {
$protocol = 'http';
}
このように書いても意味は同じです。
リバースプロキシやロードバランサー配下での注意点
$_SERVER['HTTPS'] による判定は、多くの環境で使えます。
ただし、CDN、ロードバランサー、リバースプロキシなどを使っている環境では、期待通りに判定できないことがあります。
たとえば、次のような構成です。
ユーザー
↓ HTTPS
CDN / ロードバランサー / リバースプロキシ
↓ HTTP
PHPアプリケーションサーバー
この場合、ユーザーは https://example.com にアクセスしていますが、PHPアプリケーションサーバーから見るとHTTP通信に見えることがあります。
その結果、$_SERVER['HTTPS'] が空になり、実際にはHTTPSなのに http と判定してしまう可能性があります。
このような環境では、HTTP_X_FORWARDED_PROTO などのヘッダーを使って判定することがあります。
<?php
if (!empty($_SERVER['HTTP_X_FORWARDED_PROTO'])) {
$protocol = ($_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') ? 'https' : 'http';
} else {
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
}
ただし、HTTP_X_FORWARDED_PROTO もリクエストヘッダー由来の値です。
そのため、無条件に信頼するのは危険です。信頼できるプロキシやロードバランサーから送られてきた場合のみ使うようにしましょう。
現在の完全URLを取得する関数
シンプルな関数
複数のページで現在URLを取得したい場合は、関数にしておくと便利です。
<?php
function getCurrentUrl(bool $withQuery = true): string
{
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
$host = $_SERVER['HTTP_HOST'] ?? '';
$requestUri = $_SERVER['REQUEST_URI'] ?? '/';
if (!$withQuery) {
$requestUri = parse_url($requestUri, PHP_URL_PATH) ?: '/';
}
return $protocol . '://' . $host . $requestUri;
}
使い方は以下です。
<?php
echo getCurrentUrl();
クエリ文字列も含めた現在URLが出力されます。
たとえば、現在のURLが以下の場合、
https://example.com/blog/article.php?id=123&page=2
出力結果は次のようになります。
https://example.com/blog/article.php?id=123&page=2
クエリ文字列を除外して取得する
先ほどの関数では、引数に false を渡すことで、クエリ文字列を除外できます。
<?php
echo getCurrentUrl(false);
現在のURLが以下の場合、
https://example.com/blog/article.php?id=123&page=2
出力結果は次のようになります。
https://example.com/blog/article.php
SEO用のcanonical URLを作る場合など、クエリ文字列を除外したいケースで使えます。
本番向けにホスト名を制限した関数
実務で使う場合は、HTTP_HOST をそのまま使うより、許可するホスト名を制限したほうが安全です。
<?php
function getCurrentUrl(bool $withQuery = true): string
{
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
$allowedHosts = ['example.com', 'www.example.com'];
$host = $_SERVER['HTTP_HOST'] ?? 'example.com';
if (!in_array($host, $allowedHosts, true)) {
$host = 'example.com';
}
$requestUri = $_SERVER['REQUEST_URI'] ?? '/';
if (!$withQuery) {
$requestUri = parse_url($requestUri, PHP_URL_PATH) ?: '/';
}
return $protocol . '://' . $host . $requestUri;
}
このコードでは、HTTP_HOST が許可リストに含まれていない場合、デフォルトで example.com を使うようにしています。
本番サイトでは、example.com の部分を実際のドメインに置き換えてください。
クエリ文字列なしの現在URLを取得する方法
parse_url()を使う
現在のURLからクエリ文字列を除外したい場合は、parse_url() を使うと便利です。
<?php
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
$host = $_SERVER['HTTP_HOST'] ?? '';
$requestUri = $_SERVER['REQUEST_URI'] ?? '/';
$path = parse_url($requestUri, PHP_URL_PATH);
$urlWithoutQuery = $protocol . '://' . $host . $path;
echo $urlWithoutQuery;
現在のURLが以下だった場合、
https://example.com/blog/article.php?id=123&page=2
出力結果は次のようになります。
https://example.com/blog/article.php
parse_url()を使うときの注意点
parse_url() は、URLを構成要素に分解するための関数です。
たとえば、以下のような要素を取り出すときに使えます。
- スキーム
- ホスト名
- パス
- クエリ文字列
- フラグメント
ただし、parse_url() はURLが正しいかどうかを検証する関数ではありません。
つまり、URLの妥当性チェックをしたい場合には、parse_url() だけでは不十分です。
URLの検証には、用途に応じて filter_var() などを使います。
<?php
$url = 'https://example.com';
if (filter_var($url, FILTER_VALIDATE_URL)) {
echo '正しいURLです';
}
クエリ文字列だけを取得する方法
$_SERVER['QUERY_STRING']を使う
URLの ? 以降の部分を取得したい場合は、$_SERVER['QUERY_STRING'] を使います。
<?php
echo $_SERVER['QUERY_STRING'] ?? '';
たとえば、現在のURLが以下だった場合、
https://example.com/search.php?q=php&page=2
出力結果は次のようになります。
q=php&page=2
クエリ文字列全体をそのまま扱いたい場合は、QUERY_STRING が便利です。
個別のパラメータを取得する場合は$_GETを使う
クエリ文字列全体ではなく、個別のパラメータを取得したい場合は $_GET を使います。
<?php
$q = $_GET['q'] ?? '';
$page = $_GET['page'] ?? 1;
echo $q;
echo $page;
URLが以下の場合、
https://example.com/search.php?q=php&page=2
$_GET['q'] には次の値が入ります。
php
$_GET['page'] には次の値が入ります。
2
検索フォームやページネーションなどでは、QUERY_STRING よりも $_GET を使うことが多いです。
現在のファイル名やスクリプト名を取得する方法
SCRIPT_NAMEを使う
現在実行されているスクリプトのパスを取得したい場合は、$_SERVER['SCRIPT_NAME'] を使います。
<?php
echo $_SERVER['SCRIPT_NAME'] ?? '';
たとえば、以下のように表示されます。
/blog/article.php
現在実行中のPHPファイルを知りたい場合に使えます。
PHP_SELFを使う場合の注意点
$_SERVER['PHP_SELF'] でも、現在のスクリプト名を取得できます。
<?php
echo $_SERVER['PHP_SELF'];
ただし、PHP_SELF はHTMLにそのまま出力すると、XSSの原因になる可能性があります。
そのため、表示する場合は必ずエスケープしてください。
<?php
echo htmlspecialchars($_SERVER['PHP_SELF'] ?? '', ENT_QUOTES, 'UTF-8');
現在URLを取得したい場合は、基本的に PHP_SELF ではなく、REQUEST_URI を使うほうが無難です。
現在のディレクトリURLを取得する方法
dirname()を使ってディレクトリを取得する
現在のURLが以下だったとします。
https://example.com/blog/article.php?id=123
このURLから、現在のディレクトリURLである次のURLを取得したい場合があります。
https://example.com/blog/
その場合は、dirname() を使います。
<?php
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
$host = $_SERVER['HTTP_HOST'] ?? '';
$path = parse_url($_SERVER['REQUEST_URI'] ?? '/', PHP_URL_PATH);
$directoryUrl = $protocol . '://' . $host . rtrim(dirname($path), '/\\') . '/';
echo $directoryUrl;
出力例は以下です。
https://example.com/blog/
ルート直下の場合の注意点
dirname() を使う場合、ルート直下のページでは扱いに注意が必要です。
たとえば、現在のURLが以下だった場合、
https://example.com/index.php
dirname('/index.php') は / を返します。
そのため、URLを組み立てるときにスラッシュが重複したり、不足したりしないようにする必要があります。
実務では、URLの結合処理を関数化しておくとミスを減らせます。
HTMLに現在URLを出力するときの注意点
htmlspecialchars()でエスケープする
取得した現在URLをHTMLに出力する場合は、必ずエスケープしましょう。
<?php
$currentUrl = getCurrentUrl();
?>
<p>現在のURL:<?= htmlspecialchars($currentUrl, ENT_QUOTES, 'UTF-8') ?></p>
リンクの href 属性に入れる場合も同じです。
<a href="<?= htmlspecialchars($currentUrl, ENT_QUOTES, 'UTF-8') ?>">
現在のページ
</a>
URLは安全そうに見えますが、HTTP_HOST や REQUEST_URI など、リクエストに由来する値を含むことがあります。
そのため、HTMLに出力するときは必ずエスケープするのが基本です。
エスケープしないと起こり得る問題
エスケープせずに出力すると、悪意のあるリクエストによってHTMLが崩れたり、スクリプトが実行されたりする可能性があります。
特に、以下のような出力は避けるべきです。
<?php
echo $_SERVER['REQUEST_URI'];
HTML上に出す場合は、次のようにしましょう。
<?php
echo htmlspecialchars($_SERVER['REQUEST_URI'] ?? '', ENT_QUOTES, 'UTF-8');
リダイレクトに現在URLを使う場合
ログイン後に元のページへ戻す例
現在URLは、ログイン後に元のページへ戻す処理などで使われることがあります。
<?php
$currentUrl = getCurrentUrl();
$loginUrl = '/login.php?redirect=' . urlencode($currentUrl);
header('Location: ' . $loginUrl);
exit;
このようにすれば、ログインページに現在URLを渡し、ログイン後に戻すような処理を作れます。
オープンリダイレクトに注意する
ただし、リダイレクト処理では注意が必要です。
ユーザーが任意のURLを redirect に指定できるようにしてしまうと、外部サイトへの誘導に悪用される可能性があります。
たとえば、次のようなURLです。
/login.php?redirect=https://evil.example
このようなURLを許してしまうと、自サイトを経由して悪意のあるサイトへ誘導される可能性があります。
そのため、ログイン後の戻り先には、完全URLではなく、自サイト内のパスだけを渡すほうが安全です。
<?php
$redirectPath = $_SERVER['REQUEST_URI'] ?? '/';
$loginUrl = '/login.php?redirect=' . urlencode($redirectPath);
header('Location: ' . $loginUrl);
exit;
戻り先を受け取る側でも、外部URLではなく、自サイト内のパスだけを許可するようにしましょう。
<?php
$redirect = $_GET['redirect'] ?? '/';
if (!str_starts_with($redirect, '/')) {
$redirect = '/';
}
header('Location: ' . $redirect);
exit;
SEOでcanonical URLを作る場合
クエリ文字列を除外したURLを使う
SEO目的でcanonical URLを出力する場合、クエリ文字列を除外したURLを使いたいケースがあります。
<?php
$canonicalUrl = getCurrentUrl(false);
?>
<link rel="canonical" href="<?= htmlspecialchars($canonicalUrl, ENT_QUOTES, 'UTF-8') ?>">
たとえば、以下のようなURLにアクセスされた場合、
https://example.com/article.php?id=123&utm_source=x
canonicalとしては、次のようなURLを出したいケースがあります。
https://example.com/article.php
ただし、SEO上は「現在アクセスしているURLから自動生成したURL」をそのままcanonicalにするより、サイト側で定義した正規URLを出すほうが理想です。
canonical URLは正規URLを明示するのが基本
同じ内容を表示するURLが複数ある場合、canonicalには代表となるURLを指定します。
たとえば、以下のURLが同じページを表示するとします。
https://example.com/article.php?id=123
https://example.com/article.php?id=123&utm_source=x
https://example.com/article/123/
この場合、canonicalには意図した正規URLを指定します。
<link rel="canonical" href="https://example.com/article/123/">
マーケティング施策で使う utm_source や utm_medium などの計測パラメータは、canonical URLには含めないことが多いです。
SEOを意識するなら、現在URLを機械的に出力するのではなく、ページごとに正しい正規URLを出す設計にすることが重要です。
WordPressで現在のURLを取得する方法
home_url()とREQUEST_URIを使う
WordPressで現在のURLを取得したい場合は、次のように書くことがあります。
<?php
$current_url = home_url($_SERVER['REQUEST_URI'] ?? '/');
echo esc_url($current_url);
home_url() は、WordPressサイトのホームURLを取得する関数です。
$_SERVER['REQUEST_URI'] と組み合わせることで、現在アクセスしているURLを組み立てられます。
WordPressではesc_url()で出力する
WordPressでURLをHTMLに出力するときは、esc_url() を使うのが基本です。
<?php
echo esc_url($current_url);
リンクに使う場合も同じです。
<a href="<?php echo esc_url($current_url); ?>">
現在のページ
</a>
WordPressでは、通常のPHPの htmlspecialchars() よりも、URL用に用意された esc_url() を使うほうが適しています。
投稿や固定ページのURLならget_permalink()を使う
WordPressで投稿ページや固定ページのURLを取得したい場合は、現在URLを自作するより get_permalink() を使うほうが適切です。
<?php
echo esc_url(get_permalink());
get_permalink() は、投稿や固定ページのパーマリンクを取得する関数です。
以下のようなページでは、get_permalink() が使いやすいです。
- 投稿詳細ページ
- 固定ページ
- カスタム投稿タイプの詳細ページ
一方で、以下のようなページでは、get_permalink() だけでは現在URLを表せないことがあります。
- 検索結果ページ
- カテゴリアーカイブ
- タグアーカイブ
- 投稿タイプアーカイブ
- ページネーション付き一覧
- 絞り込み条件付き一覧
投稿や固定ページの正規URLを取得したい場合は get_permalink()、現在表示中のURLを取得したい場合は home_url($_SERVER['REQUEST_URI']) のように、用途に応じて使い分けましょう。
HTTP_HOSTとSERVER_NAMEの違い
HTTP_HOSTの特徴
HTTP_HOST は、リクエストの Host ヘッダーに由来する値です。
ユーザーが実際にアクセスしたホスト名を反映しやすいという特徴があります。
たとえば、同じサーバーに以下の複数のドメインが向いている場合、
example.com
www.example.com
test.example.com
HTTP_HOST には、アクセスされたホスト名が入ることがあります。
www.example.com
ただし、ヘッダー由来の値なので、信頼しすぎないことが大切です。
SERVER_NAMEの特徴
SERVER_NAME は、Webサーバーの設定に基づくサーバー名です。
<?php
echo $_SERVER['SERVER_NAME'] ?? '';
HTTP_HOST と違い、ユーザーがアクセスしたホスト名をそのまま反映するとは限りません。
サーバー設定によっては、実際にアクセスされたドメインとは異なる値になることがあります。
実務では固定設定値を使うのも有効
本番サイトのURLが決まっている場合は、HTTP_HOST や SERVER_NAME から動的に取得するより、設定値として持つほうが安全なこともあります。
<?php
define('BASE_URL', 'https://example.com');
または、環境変数を使います。
<?php
$baseUrl = $_ENV['APP_URL'] ?? 'https://example.com';
特に、メール本文に入れるURLやパスワードリセットURLなどは、固定のベースURLから作るほうが安全です。
用途別のおすすめコード
現在の完全URLを取得したい場合
<?php
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
$host = $_SERVER['HTTP_HOST'] ?? '';
$requestUri = $_SERVER['REQUEST_URI'] ?? '/';
$currentUrl = $protocol . '://' . $host . $requestUri;
echo $currentUrl;
ドメインなしで現在のパスを取得したい場合
<?php
echo $_SERVER['REQUEST_URI'] ?? '/';
クエリ文字列なしで現在URLを取得したい場合
<?php
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
$host = $_SERVER['HTTP_HOST'] ?? '';
$path = parse_url($_SERVER['REQUEST_URI'] ?? '/', PHP_URL_PATH);
echo $protocol . '://' . $host . ($path ?: '/');
クエリ文字列だけを取得したい場合
<?php
echo $_SERVER['QUERY_STRING'] ?? '';
個別のGETパラメータを取得したい場合
<?php
$id = $_GET['id'] ?? null;
echo $id;
WordPressで現在URLを取得したい場合
<?php
$current_url = home_url($_SERVER['REQUEST_URI'] ?? '/');
echo esc_url($current_url);
WordPressで投稿URLを取得したい場合
<?php
echo esc_url(get_permalink());
PHPで現在URLを取得するときの注意点
$_SERVERの値は環境によって異なる
$_SERVER には、サーバーやリクエストに関する情報が入っています。
ただし、すべての項目が必ず存在するとは限りません。
そのため、実務では次のように ?? を使ってデフォルト値を用意すると安心です。
<?php
$requestUri = $_SERVER['REQUEST_URI'] ?? '/';
$host = $_SERVER['HTTP_HOST'] ?? 'example.com';
未定義の値をそのまま使うと、環境によっては警告が出ることがあります。
ユーザー入力に近い値として扱う
$_SERVER['REQUEST_URI'] や $_SERVER['HTTP_HOST'] は、リクエスト内容に由来する値です。
そのため、完全に安全な値として扱うのではなく、ユーザー入力に近い値として考えるのが無難です。
HTMLに出すときはエスケープする。
<?php
echo htmlspecialchars($currentUrl, ENT_QUOTES, 'UTF-8');
リダイレクトに使うときは外部URLを許可しない。
<?php
$redirect = $_GET['redirect'] ?? '/';
if (!str_starts_with($redirect, '/')) {
$redirect = '/';
}
ホスト名を使うときは許可リストを用意する。
<?php
$allowedHosts = ['example.com', 'www.example.com'];
このような対策を入れることで、より安全に現在URLを扱えます。
まとめ
PHPで現在のURLを取得する基本は、次の3つを組み合わせる方法です。
<?php
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
$host = $_SERVER['HTTP_HOST'] ?? '';
$requestUri = $_SERVER['REQUEST_URI'] ?? '/';
$currentUrl = $protocol . '://' . $host . $requestUri;
現在のURLを取得するうえで重要なポイントは次の通りです。
| 目的 | 使用する値・関数 |
|---|---|
| パスとクエリ文字列を取得 | $_SERVER['REQUEST_URI'] |
| ホスト名を取得 | $_SERVER['HTTP_HOST'] |
| HTTPS判定 | $_SERVER['HTTPS'] |
| クエリ文字列のみ取得 | $_SERVER['QUERY_STRING'] |
| 個別パラメータ取得 | $_GET |
| クエリなしURL取得 | parse_url() |
| WordPressの現在URL | home_url($_SERVER['REQUEST_URI']) |
| WordPressの投稿URL | get_permalink() |
ただし、実務では以下の点に注意が必要です。
HTTP_HOSTはヘッダー由来なので、重要な処理では許可リストを使うREQUEST_URIやHTTP_HOSTをHTMLに出力するときはエスケープする$_SERVER['HTTPS']だけでは、プロキシ配下でHTTPS判定がずれることがあるX-Forwarded-Protoを使う場合は、信頼できるプロキシからの値だけ使う- リダイレクトに現在URLを使う場合は、オープンリダイレクトに注意する
- SEOのcanonical URLは、現在URLをそのまま出すより正規URLを明示するほうが望ましい
- WordPressでは
esc_url()やget_permalink()を用途に応じて使う
単純に現在URLを取得するだけなら、以下の関数が使いやすいです。
<?php
function getCurrentUrl(bool $withQuery = true): string
{
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
$host = $_SERVER['HTTP_HOST'] ?? '';
$requestUri = $_SERVER['REQUEST_URI'] ?? '/';
if (!$withQuery) {
$requestUri = parse_url($requestUri, PHP_URL_PATH) ?: '/';
}
return $protocol . '://' . $host . $requestUri;
}
本番環境で安全性を重視するなら、ホスト名の許可リストも入れておきましょう。
<?php
function getCurrentUrl(bool $withQuery = true): string
{
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
$allowedHosts = ['example.com', 'www.example.com'];
$host = $_SERVER['HTTP_HOST'] ?? 'example.com';
if (!in_array($host, $allowedHosts, true)) {
$host = 'example.com';
}
$requestUri = $_SERVER['REQUEST_URI'] ?? '/';
if (!$withQuery) {
$requestUri = parse_url($requestUri, PHP_URL_PATH) ?: '/';
}
return $protocol . '://' . $host . $requestUri;
}
PHPで現在URLを取得する処理はシンプルに見えますが、実務ではセキュリティ、サーバー構成まで考慮する必要があります。
用途に応じて、簡易的な取得方法と安全性を高めた取得方法を使い分けることが大切です。
以上、PHPで現在のURLを取得する方法についてでした。
最後までお読みいただき、ありがとうございました。









