HOWTO · PHP
PHP で現在のフル URL を取得
このチュートリアルでは、PHP で現在の URL を取得する方法を紹介します。
このページの内容
現在のPHPリクエストのURLを確認または組み立てるには、リクエストのスキーム、ホスト、URIを組み合わせます。クエリパラメーターに基づいてページを表示するときや、リクエストされたアドレスを記録するときに役立ちます。組み立てたURLはあくまでデータです。リダイレクトに使う場合は、許可する遷移先を別途判断する必要があります。
リクエストデータから現在のURLを組み立てる
PHPでは、常に完全な現在のURLを表す単一の$_SERVER値が得られるわけではありません。サーバーはリクエスト情報を個別に提供するため、アプリケーション側で必要な値を組み合わせます。一般的なWebリクエストでは、スキームはhttpまたはhttpsで、ホストにはポート番号が含まれる場合があり、リクエストURIにはパスとクエリ文字列が含まれます。
$_SERVERからスキーム、ホスト、リクエストURIを取得する
$_SERVERは、Webサーバーと実行環境によって値が設定されるスーパーグローバル配列です。$_SERVER['HTTP_HOST']にはリクエストされたホストが入り、$_SERVER['REQUEST_URI']には通常、パスとクエリ文字列が入ります。どちらも単独では完全なURLではありません。ホストは受信したリクエストに由来するため、信頼できない入力として扱ってください。リダイレクトやメール内の絶対リンクなど、セキュリティ上重要な出力に使う前に、既知のホストと照合して検証します。
HTTPSとプロキシを考慮したリクエストを扱う
PHPがTLS経由でリクエストを直接受け取る場合、$_SERVER['HTTPS']には通常、onなどの空でない値が設定されます。スキームを選ぶ前にこの値を確認してください。すべてのサーバーで同じ値が設定されるとは限りません。$_SERVER['REQUEST_SCHEME']が利用できる場合もありますが、利用可否や意味はサーバーの設定によって異なります。
リバースプロキシを使う構成では、ブラウザーからプロキシまではHTTPSでも、プロキシからPHPまではHTTPで接続することがあります。この場合、直接のHTTPS状態が示すのは、プロキシからPHPまでの接続だけかもしれません。転送されたスキームのヘッダーを利用できるのは、アプリケーションの前段に信頼できるプロキシを明示的に設定し、そのプロキシがクライアント提供の値を削除または置換する場合に限られます。任意のリクエストから届く転送ヘッダーを信頼してはいけません。プロキシとアプリケーションの両方で信頼関係を設定するか、サーバーが確実に提供するスキームを使ってください。
パスとクエリ文字列を含める
$_SERVER['REQUEST_URI']には通常、/products.php?category=books&page=2のような値が入ります。これを追加すれば、パスとクエリ文字列の両方を保持できます。ただし、スキームやホストは含まれません。クエリ文字列には非公開情報や機密情報が含まれることがあるため、ログ、ページ出力、メール内のURLに含めてよいか検討してください。アプリケーションのルーティングやデプロイ設定を考慮せず、リクエストURIを正規URLとして扱うのは避けましょう。
方法を選び、結果を確認する
Webサーバーがリクエストを直接処理する一般的な構成では、サーバーの値を明示的に組み合わせます。次の自己完結した例では、組み立て方が分かるよう代表的なリクエスト値を使っています。この執筆段階では実行していません。
このセクションのコードと表示されるラベルや出力は英語のままです。
<?php
$_SERVER = [
'HTTPS' => 'on',
'HTTP_HOST' => 'shop.example.test',
'REQUEST_URI' => '/products.php?category=books&page=2',
];
$isHttps = isset($_SERVER['HTTPS'])
&& $_SERVER['HTTPS'] !== ''
&& strtolower((string) $_SERVER['HTTPS']) !== 'off';
$scheme = $isHttps ? 'https' : 'http';
$host = $_SERVER['HTTP_HOST'];
$requestUri = $_SERVER['REQUEST_URI'];
$currentUrl = $scheme . '://' . $host . $requestUri;
echo $currentUrl, PHP_EOL;
結果の文字列は、スキーム、ホスト、リクエストURIを組み合わせて作られます。実際のアプリケーションでは、リクエストから得た値を使い、Webサーバーや信頼済みプロキシがそれらをどのように設定するか確認してください。結果をリダイレクトに使う前にホストを検証します。現在のURLを組み立てただけでは、任意のリダイレクト先が安全になるわけではありません。