PHPで学ぶ:ドメイン、パス、プロトコルなどのURL取得テクニック

PHP

ウェブ開発において、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スクリプト内で他のファイルへのパスを指定する際に便利です。

取得例

  1. Windows(XAMPPの場合)
    • C:/xampp/htdocs
    • XAMPPでデフォルトの公開フォルダ。
  2. Xサーバーの場合
    • /home/ユーザー名/ドメイン名/public_html
    • ドメインごとにpublic_htmlがドキュメントルート。
  3. ロリポップの場合
    • /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

解説

  1. $_SERVER[‘REQUEST_URI’]: 現在のURL(パス+クエリ+フラグメント)を取得。
  2. strpos: URL内の#の位置を取得。存在しない場合はfalse。
  3. substr: #以降の文字列を切り出す。
  4. 三項演算子: フラグメントがない場合はメッセージを表示。

取得例

  1. URL: /index.php?page=2#section
    • 結果: section
  2. 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です';
}
PHP

URLの不完全性

  • 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

コメント

タイトルとURLをコピーしました