PHPでは、 Parse_urlはURLを解析し、スキーム、ホスト、パスなどのさまざまな部分を抽出する非常に実用的な機能です。ただし、サブドメイン名を取得するという要件では、 Parse_URLは「サブドメイン名」フィールドを直接提供しないため、ホストのさらなる解析の助けを借りて目標を達成する必要があります。ただし、このプロセスで簡単に見落とされるいくつかのピットと詳細があるため、以下で詳しく説明します。
parse_urlは、標準のURLでなくても、渡された文字列を解析しようとします。例えば:
$url = 'not-a-valid-url';
$parsed = parse_url($url);
print_r($parsed);
現時点では、 $解析は情報の一部のみを返すことができ、構造さえも予想どおりに完全に満たされていません。したがって、 parse_urlを使用する前にURLの合法性を検証するか、少なくともhttp:// prefixを追加することが最善です。
if (!preg_match('#^https?://#', $url)) {
$url = 'http://' . $url;
}
parse_urlはホストを返しますが、サブドメイン名を直接与えません。例えば:
$url = 'https://sub.gitbox.net/path';
$parsed = parse_url($url);
echo $parsed['host']; // 出力 sub.gitbox.net
このホストを自分で分割する必要があります。通常の慣行は、エクスプロイトを使用することです。
$hostParts = explode('.', $parsed['host']);
結果が['sub'、 'gitbox'、 'net']である場合、サブはサブドメインと見なすことができます。しかし、特に次の状況では、これは必ずしも正確ではありません。
一部の国には、 Co.ukやcom.cnなどの2層構造があります。最後の2つのフィールドを主なドメイン名として単純に扱い、残りをサブドメインとして扱うと、エラーが発生します。例えば:
$url = 'https://sub.example.co.uk';
$parsed = parse_url($url);
$hostParts = explode('.', $parsed['host']);
結果は['sub'、 'example ' 、 'co'、 'uk']になりました。
この問題を解決するには、パブリックサフィックスリスト(パブリックサフィックスリスト)を導入するか、 Jeremykendall/PHP-Domain-Parserなどのサードパーティライブラリを使用して、メインドメインとサブドメインの境界を正確に決定する必要があります。
URLがIPアドレスをホスト名として使用する場合、当然、「サブドメイン名」の概念はありません。
$url = 'http://192.168.1.1';
$parsed = parse_url($url);
echo $parsed['host']; // 出力 192.168.1.1
IPv6アドレスはより複雑で、ブラケットも含まれています。
$url = 'http://[2001:db8::1]';
$parsed = parse_url($url);
echo $parsed['host']; // 出力 [2001:db8::1]
これらの状況はどれも、サブドメインを持つドメイン名として誤って扱われるべきではありません。
parse_urlはポート番号を分離します:
$url = 'http://sub.gitbox.net:8080';
$parsed = parse_url($url);
ただし、サブドメイン名を抽出する場合、ホストにのみ注意を払う必要があり、ポート番号で干渉しないでください。通常の抽出ドメイン名を使用すると、誤ってポートをまとめて誤判断することがあります。
parse_urlを使用してサブドメインを抽出することは、複数の境界の状況を伴う万能の問題ではありません。お勧めします:
標準形式を確保するために使用する前にURLを事前に処理します。
解析後、信頼できる方法を使用して、主要なドメインとサブドメインを抽出します。
可能な場合はパブリックサフィックスリストを使用して、トップレベルおよびプライマリドメインの境界を識別します。
IPアドレスとIPv6の特別な取り扱い。
ポート番号、プロトコルプレフィックスなどの干渉要因に注意してください。
これらの詳細を包括的に考慮することによってのみ、URLの解析に急いで行き、より堅牢なシステムを構築することを避けることができます。