首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 取得根域名的多種實用方法與程式碼範例

     編輯:PHP 相關知識

從完整 URL 或主機名中精準萃取「根域名」(如 www.example.co.uk → example.co.uk)是常見需求。本文整理三種不同複雜度的方案,涵蓋常見 TLD 與國別碼(如 .com.cn、.gov.cn)。

快速取得當前請求的主機名

<?php
echo $_SERVER['HTTP_HOST'];        // 含 port(若非 80/443)
echo $_SERVER['SERVER_NAME'];      // Server 設定的主機名
// 注意:若使用反向代理,需檢查 X-Forwarded-Host

方法一:正則表達式通用解析(支援多層 TLD)

function getRootDomain($url) {
    // 確保結尾有斜線方便匹配
    $url = rtrim($url, '/') . '/';
    // 匹配 scheme:// 可選、子網域可選、主域名+頂級域
    $pattern = '~^(?:https?://)?(?:[^/]+\.)?([a-z0-9-]+\.(?:com|net|org|gov|edu|co|me|io|ai|app|dev|cn|com\.cn|net\.cn|org\.cn|gov\.cn))~i';
    if (preg_match($pattern, $url, $m)) {
        return $m[1];
    }
    // IP 直連情況
    if (preg_match('~^https?://(\d{1,3}(?:\.\d{1,3}){3})~i', $url, $m)) {
        return $m[1];
    }
    return '';
}

方法二:陣列切割法(針對 .cn 等雙層 TLD 優化)

function getRootDomainV2($host) {
    $parts = explode('.', $host);
    $cnt = count($parts);
    if ($cnt < 2) return $host;

    $twoLevelTlds = ['com','net','org','gov','edu','com.cn','net.cn','org.cn','gov.cn','cn'];
    $last = strtolower($parts[$cnt - 1]);
    $secondLast = strtolower($parts[$cnt - 2]);

    if ($last === 'cn' && in_array($secondLast, $twoLevelTlds)) {
        // xxx.com.cn / xxx.gov.cn 等
        return implode('.', array_slice($parts, -3));
    }
    // 一般情況:取最後兩段
    return $secondLast . '.' . $last;
}

方法三:使用 Public Suffix List(最嚴謹、可維護)

生產環境強烈建議引用 php-domain-parser,內建 Public Suffix List,自動處理數千種 TLD 變化:

composer require jeremykendall/php-domain-parser

use Pdp\Manager;
$manager = new Manager();
$domain = $manager->parse('https://shop.blog.example.co.uk/path');
echo $domain->getRegistrableDomain(); // example.co.uk

適用場景對照表

方法優點缺點建議場景
正則無依賴、單一函式難維護新 TLD小專案、已知域名集合
陣列切割邏輯清晰、效能極佳需手動維護雙層 TLD 列表中型專案、以 .cn/.tw 為主
Public Suffix List標準化、自動更新、最準確需 Composer、稍大所有生產環境、多國域名

選擇原則:能用 Composer 就用 Public Suffix List;受限環境下用方法二並定期更新 $twoLevelTlds 陣列。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved