「URL からドメイン取得」で何をしたいのか
まずゴールをはっきりさせます。
"https://example.com/path" → "example.com"
"https://sub.example.co.jp/page" → "sub.example.co.jp"
"http://localhost:8080/test" → "localhost"
"https://192.168.0.10/app" → "192.168.0.10"
やりたいことはシンプルで、
「URL 文字列から、ホスト部分(ドメイン)だけを安全に取り出したい」
ということです。
業務・実務では、例えばこんな場面で使います。
外部リンクが「許可されたドメインかどうか」をチェックしたい。
ログに記録された URL から、どのドメインへのアクセスが多いか集計したい。
リダイレクト先 URL が、自社ドメイン配下かどうかを検証したい。
このとき、文字列操作で無理やり https:// を削ったり、/ で explode したりすると、すぐに壊れます。
ここは素直に「URL をちゃんと分解する関数」を使うのが正解です。
PHP の基本:parse_url で URL を分解する
parse_url のイメージ
PHP には、URL を構造的に分解してくれる parse_url があります。
$url = "https://sub.example.co.jp:8443/path/to/page?x=1#top";
$parts = parse_url($url);
var_dump($parts);
PHPだいたいこんな配列になります。
array(6) {
["scheme"] => "https"
["host"] => "sub.example.co.jp"
["port"] => 8443
["path"] => "/path/to/page"
["query"] => "x=1"
["fragment"] => "top"
}
PHPこの中の host が、いわゆる「ドメイン部分」です。
なので、基本形はこうなります。
$host = parse_url($url, PHP_URL_HOST);
PHPPHP_URL_HOST を第2引数に渡すと、「欲しい要素だけ」を直接返してくれるので便利です。
一番シンプルな「ドメイン取得」ユーティリティ
まずは「ホストをそのまま返す」関数
初心者向けに、まずはこれくらいの関数から始めると分かりやすいです。
/**
* URL からホスト(ドメイン)を取得する
* 取得できない場合は null を返す
*/
function getHostFromUrl(string $url): ?string
{
$host = parse_url($url, PHP_URL_HOST);
if ($host === null || $host === false || $host === '') {
return null;
}
return $host;
}
PHP使い方の例です。
echo getHostFromUrl("https://example.com/path"); // example.com
echo getHostFromUrl("https://sub.example.co.jp/page"); // sub.example.co.jp
echo getHostFromUrl("http://localhost:8080/test"); // localhost
echo getHostFromUrl("https://192.168.0.10/app"); // 192.168.0.10
var_dump(getHostFromUrl("not a url")); // null
PHPここで大事なのは、「失敗したときに null を返す」という設計です。
URL でない文字列が来る可能性は、実務では普通にあります。
そのときに「空文字」や「false」をそのまま返すと、呼び出し側でバグの温床になります。
?string(null 許容)にしておくと、「取れなかった」という状態をはっきり表現できます。
実務向けにもう一歩:小文字にそろえておく
ホスト名は大文字小文字を区別しない
URL のホスト名は、大文字小文字を区別しません。
https://Example.com/path
![]()
Example Domain
これらは同じ場所を指します。
なので、「比較」や「ホワイトリストチェック」に使うときは、
小文字にそろえておくと扱いやすくなります。
/**
* URL からホスト(ドメイン)を取得し、小文字にそろえる
*/
function getNormalizedHostFromUrl(string $url): ?string
{
$host = parse_url($url, PHP_URL_HOST);
if ($host === null || $host === false || $host === '') {
return null;
}
return strtolower($host);
}
PHP使い方のイメージです。
echo getNormalizedHostFromUrl("https://Example.COM/path"); // example.com
PHPこれで、「example.com」と「Example.COM」を同じものとして扱えるようになります。
「許可されたドメインかどうか」を判定する例
ホワイトリストチェックの典型パターン
例えば、「自社ドメイン配下の URL だけリダイレクトを許可したい」というケース。
$allowedHost = 'example.com';
$url = $_GET['redirect'] ?? '';
$host = getNormalizedHostFromUrl($url);
if ($host === null) {
// URL としておかしい → 拒否
}
if ($host !== $allowedHost) {
// 許可されていないドメイン → 拒否
}
// OK ならリダイレクト
header('Location: ' . $url);
exit;
PHPここでのポイントは二つです。
一つ目は、「URL として解釈できないものは即座に拒否」していること。
二つ目は、「ホスト名を小文字にそろえてから比較」していること。
これだけで、「Example.com」「EXAMPLE.COM」などの表記ゆれに悩まされずに済みます。
「サブドメインも許可したい」場合の考え方
example.com とその配下(sub.example.com など)を許可する
よくある要件として、
「example.com と、そのサブドメイン(sub.example.com など)も許可したい」
というものがあります。
その場合は、こういう判定になります。
/**
* URL が、指定ドメイン配下かどうかを判定する
* 例: example.com → example.com, sub.example.com を許可
*/
function isUrlUnderDomain(string $url, string $allowedDomain): bool
{
$host = getNormalizedHostFromUrl($url);
if ($host === null) {
return false;
}
$allowedDomain = strtolower($allowedDomain);
if ($host === $allowedDomain) {
return true;
}
// 末尾が ".example.com" なら OK
return str_ends_with($host, '.' . $allowedDomain);
}
PHP使い方の例です。
var_dump(isUrlUnderDomain("https://example.com/page", "example.com")); // true
var_dump(isUrlUnderDomain("https://sub.example.com/page", "example.com")); // true
var_dump(isUrlUnderDomain("https://evil-example.com/page", "example.com")); // false
PHPここでの重要ポイントは、「末尾が .example.com かどうか」で判定していることです。
evil-example.com のような「紛らわしい別ドメイン」を誤って許可しないために、'.' . $allowedDomain でチェックしているのがミソです。
注意点:URL っぽいけどスキームがない文字列
parse_url は「スキームなし」の文字列もそれっぽく分解してしまう
例えば、こういう文字列。
$url = "example.com/path";
$host = parse_url($url, PHP_URL_HOST);
var_dump($host); // null
PHPスキーム(http:// や https://)がないと、parse_url は「ホスト」として認識しません。
実務では、ユーザーが「https:// を付けずに URL を入力してくる」ことがよくあります。
その場合は、「足りないスキームを補ってから parse_url する」という前処理を入れることもあります。
function getHostFromMaybeUrl(string $value): ?string
{
// すでにスキームが付いているかチェック
if (!preg_match('#^[a-zA-Z][a-zA-Z0-9+.-]*://#', $value)) {
// なければ https:// を仮で付ける
$value = 'https://' . $value;
}
return getHostFromUrl($value);
}
PHPこれで、
echo getHostFromMaybeUrl("example.com/path"); // example.com
echo getHostFromMaybeUrl("https://example.com/a"); // example.com
PHPのように扱えるようになります。
ただし、「本当に URL として扱っていい文字列かどうか」の判断は別問題なので、
この関数を使う場面は慎重に選んでください。
まとめ:今日からの「URL からドメイン取得」ユーティリティ
押さえておきたいポイントをコンパクトにまとめます。
URL からドメインを取るときは、文字列操作ではなく parse_url を使う。parse_url($url, PHP_URL_HOST) でホストだけを取り出し、失敗したら null を返す設計にする。
比較やホワイトリストチェックに使うなら、小文字にそろえたホスト名を使う。
サブドメインも許可したい場合は、「$host === $domain または str_ends_with($host, '.' . $domain)」という形で判定する。
核になるコードは、このくらいです。
function getHostFromUrl(string $url): ?string
{
$host = parse_url($url, PHP_URL_HOST);
if ($host === null || $host === false || $host === '') {
return null;
}
return $host;
}
function getNormalizedHostFromUrl(string $url): ?string
{
$host = getHostFromUrl($url);
return $host === null ? null : strtolower($host);
}
PHPもし、あなたのプロジェクトの中で「外部リダイレクト先 URL をそのまま信じて使っているところ」があれば、そこがこのユーティリティの出番です。
