ウェブ開発において、URLの構造やその取得方法を理解することは、動的なウェブサイトやアプリケーションを作成する際に欠かせないスキルです。
本記事では、PHPを使用してURLに関する基本情報を取得する方法から、詳細な解析や応用的な技術までを網羅的に解説します。初心者でも分かりやすいように、実用的なコード例とともに説明しています。この記事を通じて、URLの基礎をしっかり学び、サーバー環境における効率的なURL管理に役立ててください。
URLの基本情報を取得
基本的な取得方法
<?php
echo $_SERVER['REQUEST_URI']; // パスとクエリ文字列を含むURIを取得
echo "<br>";
echo $_SERVER['HTTP_HOST']; // ドメイン名を取得
?>PHP解説
- $_SERVER[‘REQUEST_URI’]
ドメイン以下のリクエストURI(パス+クエリ文字列)を取得します。 - $_SERVER[‘HTTP_HOST’]
ホスト名(ドメイン名)を取得します。
取得例
- URL: http://example.com/index.php?page=2&sort=asc
- $_SERVER[‘REQUEST_URI’]: /index.php?page=2&sort=asc
- $_SERVER[‘HTTP_HOST’]: example.com
プロトコルの取得
<?php
if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') {
$protocol = 'https';
} else {
$protocol = 'http';
}
echo $protocol;
?>PHP解説
$_SERVER[‘HTTPS’]がセットされており、値が’off’でない場合、HTTPS通信と判断します。これにより、httpかhttpsかを動的に判定可能です。
取得例
HTTP通信の場合:http
HTTPS通信の場合:https
ホスト名の取得
<?php
$host = gethostname();
echo $host;
?>PHP解説
- ドメイン名が必要なら、$_SERVER[‘HTTP_HOST’]を使用。
- gethostname(): サーバーやPCのホスト名(コンピュータ名)を取得。
- ローカル環境: 自分のPC名(例: DESKTOP-12345 や ubuntu-local)。
- 本番環境: サーバーに設定されたホスト名(例: server1 や prod-server)。
本番環境のサーバーでは、ホスティングサービスやサーバーの設定に応じたホスト名が返されます。
例: AWSではインスタンスの名前がホスト名になることが多い。
例: レンタルサーバーの場合は、プロバイダーが設定したホスト名が返されます。
取得例
ローカル環境
- 出力例(Windows): DESKTOP-12345
- 出力例(Linux): ubuntu-local
本番環境
- 出力例: server1
- 出力例(AWS): ip-172-31-22-33
ポートの取得
<?php
$port = $_SERVER['SERVER_PORT'];
echo $port;
?>PHP解説
$_SERVER[‘SERVER_PORT’]は、サーバーが使用しているポート番号を取得します。
取得例
カスタムポート:例)8080
デフォルトHTTPポート:80
デフォルトHTTPSポート:443
サーバー環境の基本情報を取得
ドキュメントルートを取得
<?php
// ドキュメントルートを取得
$document_root = $_SERVER['DOCUMENT_ROOT'];
echo "DOCUMENT_ROOT: " . $document_root . "<br>";
?>PHP解説
- サーバーのドキュメントルート(公開ディレクトリ)を返します。
- 主にファイル操作時に使用します。たとえば、PHPスクリプト内で他のファイルへのパスを指定する際に便利です。
取得例
- Windows(XAMPPの場合)
- C:/xampp/htdocs
- XAMPPでデフォルトの公開フォルダ。
- Xサーバーの場合
- /home/ユーザー名/ドメイン名/public_html
- ドメインごとにpublic_htmlがドキュメントルート。
- ロリポップの場合
- /home/users/1/main.jp-ランダム文字列/web
- webがドキュメントルート。ランダム文字列は契約ごとに異なる。
サーバー名を取得
<?php
$server_name = $_SERVER['SERVER_NAME'];
echo "SERVER_NAME: " . $server_name . "<br>";
?>PHP解説
- クライアントがアクセスしたホスト名(サーバー名)を返します。
- 動的なホスト名の処理や、サイトのマルチドメイン対応時に使用されます。
取得例
- SERVER_NAME: localhostやexample.com。
URLの詳細情報を解析
パラメーターの取得
<?php
$parameters = $_SERVER['QUERY_STRING'] ?: "クエリ文字列は存在しません";
echo $parameters;
?>PHP解説
$_SERVER[‘QUERY_STRING’]は、URLのクエリ文字列部分(?以降)を取得します。
取得例
URL: http://example.com/index.php?page=2&sort=asc
結果:page=2&sort=asc
フラグメント(アンカー)の取得
<?php
$url = $_SERVER['REQUEST_URI'];
echo ($pos = strpos($url, '#')) !== false ? substr($url, $pos + 1) : 'フラグメントは存在しません。';
?>PHP解説
- $_SERVER[‘REQUEST_URI’]: 現在のURL(パス+クエリ+フラグメント)を取得。
- strpos: URL内の
#の位置を取得。存在しない場合はfalse。 - substr:
#以降の文字列を切り出す。 - 三項演算子: フラグメントがない場合はメッセージを表示。
取得例
- URL: /index.php?page=2#section
- 結果: section
- URL: /index.php?page=2
- 結果: フラグメントは存在しません。
リファラ(直前のページのURL)を取得
<?php
$current_url = $_SERVER['HTTP_REFERER'];
echo $current_url;
?>PHP解説
$_SERVER[‘HTTP_REFERER’]は、ユーザーが直前に訪れていたページのURLを取得します。ただし、取得できない場合もあります。
取得例
- 前のページ:http://example.com/home
結果:http://example.com/home
URL全体の構築と管理
ベースURLの取得
<?php
$protocol = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https://' : 'http://';
$base_url = $protocol . $_SERVER['HTTP_HOST'];
echo $base_url;
?>PHP解説
プロトコルとホスト名を組み合わせて、サイトのベースURLを取得します。
取得例
- URL: http://example.com/index.php?page=2
結果:http://example.com
プロトコルを含めた完全なURLを取得
<?php
$protocol = isset($_SERVER['HTTPS']) ? 'https://' : 'http://';
$current_url = $protocol . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
echo $current_url;
?>PHP解説
- プロトコル判定: $_SERVER[‘HTTPS’]がセットされている場合はhttps://を、それ以外はhttp://を使用します。
- 完全なURL構築: プロトコル、ホスト名、リクエストURIを結合します。
取得例
- URL: https://example.com/index.php?page=2
結果:https://example.com/index.php?page=2
ポート番号や詳細な条件でプロトコルを判定
<?php
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off'
|| $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
$current_url = $protocol . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
echo $current_url;
?>PHP解説
- HTTPS判定: $_SERVER[‘HTTPS’]と$_SERVER[‘SERVER_PORT’]を併用し、HTTPS通信を厳密に判定します。
- URL構築: 上記の条件で判定したプロトコルを使用してURLを作成します。
取得例
- HTTPS通信、ポート443の場合: https://example.com/index.php?page=2
- HTTP通信の場合: http://example.com/index.php?page=2
URL構築の応用技術
sprintfを使ったURL取得
<?php
$current_url = sprintf(
"%s://%s%s",
isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http',
$_SERVER['HTTP_HOST'],
$_SERVER['REQUEST_URI']
);
echo $current_url;
?>PHP解説
- sprintfの使用: sprintf関数を使い、フォーマット指定子を使用してURLを構築します。
- プロトコル判定: isset($_SERVER[‘HTTPS’])とその値を使用して判定します。
取得例
- HTTPS通信の場合: https://example.com/index.php?page=2
- HTTP通信の場合: http://example.com/index.php?page=2
スクリプト名とクエリ文字列を組み合わせて取得
<?php
$base_url = "http://" . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
$query_string = $_SERVER['QUERY_STRING'];
$current_url = $base_url . '?' . $query_string;
echo $current_url;
?>PHP解説
- $_SERVER[‘PHP_SELF’]: 現在実行中のスクリプトのパス(index.phpなど)を取得します。
- $_SERVER[‘QUERY_STRING’]: URLのクエリ文字列部分(
?以降)を取得します。 - 完全なURL構築: スクリプト名とクエリ文字列を組み合わせてURLを構築します。
取得例
- URL: http://example.com/path/index.php?page=2&sort=asc
- $_SERVER[‘PHP_SELF’]: /path/index.php
- $_SERVER[‘QUERY_STRING’]: page=2&sort=asc
- 結果:http://example.com/path/index.php?page=2&sort=asc
URL解析に便利なparse_url関数
parse_urlは、PHPで提供される強力な関数の1つで、URLを解析してその構成要素(スキーム、ホスト、パス、クエリ、フラグメントなど)を簡単に取得するために使われます。
URL操作を伴うWebアプリケーションやAPI開発では非常に役立ち、コードの簡潔化や可読性の向上に寄与します。ただし、正しく使わないと予期しない動作を引き起こすこともあるため、適切な使い方と注意点を理解しておく必要があります。
コード
<?php
$url = 'http://127.0.0.1:5502/index.html?page=2#pagetop';
// URLを解析してすべての情報を取得
$parsed_url = parse_url($url);
// 各要素の出力
echo "スキーム: " . ($parsed_url['scheme'] ?? 'なし') . "<br>";
echo "ホスト: " . ($parsed_url['host'] ?? 'なし') . "<br>";
echo "ポート: " . ($parsed_url['port'] ?? 'なし') . "<br>";
echo "パス: " . ($parsed_url['path'] ?? 'なし') . "<br>";
echo "クエリ: " . ($parsed_url['query'] ?? 'なし') . "<br>";
echo "フラグメント: " . ($parsed_url['fragment'] ?? 'なし') . "<br>";
?>PHP解説
- parse_urlの戻り値は連想配列。複数の要素を一度に取得できます。
- 全体を一括で解析する場合に便利です。
<?php
$url = 'http://127.0.0.1:5502/index.html?page=2#pagetop';
// 必要な要素だけ取得
$scheme = parse_url($url, PHP_URL_SCHEME);
$host = parse_url($url, PHP_URL_HOST);
$port = parse_url($url, PHP_URL_PORT);
$path = parse_url($url, PHP_URL_PATH);
$query = parse_url($url, PHP_URL_QUERY);
$fragment = parse_url($url, PHP_URL_FRAGMENT);
// 各要素の出力
echo "スキーム: " . ($scheme ?: 'なし') . "<br>";
echo "ホスト: " . ($host ?: 'なし') . "<br>";
echo "ポート: " . ($port ?: 'なし') . "<br>";
echo "パス: " . ($path ?: 'なし') . "<br>";
echo "クエリ: " . ($query ?: 'なし') . "<br>";
echo "フラグメント: " . ($fragment ?: 'なし') . "<br>";
?>PHP解説
- 第二引数を指定すると、特定の要素だけを直接取得できます。
- 必要な情報が決まっている場合に効率的です。
注意点
信頼できないURLの扱い
- ユーザー入力を直接parse_urlに渡す場合、バリデーションを行う必要があります。
- 解決策: filter_varを使ってURLを検証。
if (!filter_var($url, FILTER_VALIDATE_URL)) {
echo '無効なURLです';
}PHPURLの不完全性
- URLが不完全な場合、parse_urlは空の値やfalseを返すことがあります。
- 解決策: 結果を確認してエラーハンドリングを行う。
$parsed = parse_url($url);
if ($parsed === false) {
echo '解析に失敗しました';
}PHPフラグメント(アンカー)はクライアント側のみ
- フラグメント(#以降)はサーバーに送信されないため、$_SERVER[‘REQUEST_URI’]では取得できません。指定URLを扱う場合のみ取得可能。
ポート番号が省略されるケース
- 標準ポート(80, 443)の場合、ポート番号が返されない場合があります。
- 解決策: ポート番号が返されない場合のデフォルト値を設定。
$port = $parsed['port'] ?? ($parsed['scheme'] === 'https' ? 443 : 80);PHP絶対パスでないURLの扱い
- parse_urlは絶対URLだけでなく相対パスにも使用可能。ただし、結果が不完全になることがあります。
まとめ
parse_urlは、URL操作が必要な場面で非常に便利な関数ですが、信頼できない入力や不完全なURLに対するエラーハンドリングを慎重に行う必要があります。バリデーションやサニタイズを適切に組み合わせることで、安全かつ効果的に利用できます。用途に応じて、全体の解析(第二引数なし)や特定の要素だけを取得する方法を使い分けることで、より柔軟に活用できるでしょう。
最後に
この記事では、PHPを活用したURLの基本情報取得から詳細解析、さらに応用的なURL構築技術までを段階的に解説しました。ウェブアプリケーションを構築する際、これらの技術を活用すれば、動的なリクエスト処理やページ遷移、URL管理がよりスムーズになります。
特に、parse_url やプロトコル判定などは、セキュリティやユーザビリティを向上させるための重要なポイントです。ぜひ今回の内容を参考に、URL操作のスキルを実務で活用してください。分からない部分があれば、ぜひコード例を実際に試してみて、自分のプロジェクトに取り入れてみましょう。
後コードをまとめたので、こちらもお使いください。
<?php
// パスとクエリ文字列を含むURIを取得
echo $_SERVER['REQUEST_URI'];
echo "<br>";
// ドメイン名を取得
echo $_SERVER['HTTP_HOST'];
echo "<br>";
// プロトコルを判定して取得
$protocol = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
echo $protocol;
echo "<br>";
// ホスト名を取得
$host = gethostname();
echo $host;
echo "<br>";
// ポート番号を取得
$port = $_SERVER['SERVER_PORT'];
echo $port;
echo "<br>";
// ドキュメントルートを取得
$document_root = $_SERVER['DOCUMENT_ROOT'];
echo "DOCUMENT_ROOT: " . $document_root . "<br>";
// サーバー名を取得
$server_name = $_SERVER['SERVER_NAME'];
echo "SERVER_NAME: " . $server_name . "<br>";
// クエリ文字列を取得
$parameters = $_SERVER['QUERY_STRING'] ?: "クエリ文字列は存在しません";
echo $parameters;
echo "<br>";
// フラグメントを取得
$url = $_SERVER['REQUEST_URI'];
echo ($pos = strpos($url, '#')) !== false ? substr($url, $pos + 1) : 'フラグメントは存在しません。';
echo "<br>";
// HTTPリファラを取得
$current_url = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : 'リファラは存在しません。';
echo $current_url;
echo "<br>";
// ベースURLを取得
$base_url = $protocol . "://" . $_SERVER['HTTP_HOST'];
echo $base_url;
echo "<br>";
// 現在のURLを取得(HTTPSチェック込み)
$current_url = $protocol . "://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
echo $current_url;
echo "<br>";
// 現在のURLを取得(sprintfを使用)
$current_url = sprintf(
"%s://%s%s",
isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http',
$_SERVER['HTTP_HOST'],
$_SERVER['REQUEST_URI']
);
echo $current_url;
echo "<br>";
// クエリ文字列付きの完全URLを構築
$base_url = $protocol . "://" . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
$query_string = $_SERVER['QUERY_STRING'];
$current_url = $base_url . '?' . $query_string;
echo $current_url;
?>PHP


コメント