PHP取域名怎么做?php获取当前域名函数详解

PHP取域名最标准的方法是使用$_SERVER['HTTP_HOST']配合parse_url解析$_SERVER['REQUEST_URI'],但真正严谨的做法是先判断$_SERVER['SERVER_NAME'],再结合HTTPS状态拼接完整URL。

很多开发者写PHP程序时,第一步就是获取当前访问的域名,用来生成绝对链接、做跨域判断、或者调用第三方API,但网上搜到的代码五花八门,有的用了$_SERVER['SERVER_NAME'],有的用$_SERVER['HTTP_HOST'],还有的直接拿$_SERVER['REQUEST_URI']切来切去,到底哪个靠谱?这篇文章不讲虚的,直接给你能落地的代码和场景拆解。

PHP获取域名的基础方法:三种内置变量对比

PHP里能碰到的域名相关变量基本就是$_SERVER里的那几个键,搞懂它们的区别,比背一百行代码都强,下面这张表是核心。

变量名 典型值 风险点
$_SERVER['HTTP_HOST'] 请求头里的Host字段,包含端口号 www.example.com:8080 可被HTTP头伪造,但大多数现代框架仍然用它
$_SERVER['SERVER_NAME'] 服务器配置中的服务器名 www.example.com 受Apache/Nginx的ServerName配置影响,一般不含端口
$_SERVER['SERVER_ADDR'] 服务器IP地址 168.1.1 不是域名

取纯域名(不带端口)的标准做法

$host = $_SERVER['HTTP_HOST'] ?? $_SERVER['SERVER_NAME'];
$domain = preg_replace('/:d+$/', '', $host); // 去掉端口

这个写法兼容了HTTP_HOST缺失的情况,同时用正则把端口号剥离,注意是PHP 7+的空合并运算符,老项目改成isset()判断。

为什么不能用$_SERVER['REQUEST_URI']直接取域名?

REQUEST_URI里存的是路径和查询字符串,比如/index.php?id=1,它压根不包含域名,但很多老教程会教你先拼$_SERVER['HTTP_HOST']再拼REQUEST_URI,这就是拿两个变量硬凑,真正需要的是HTTP_HOST和HTTPS状态组合成的完整URL。

完整URL拼法

$scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
$fullUrl = $scheme . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];

这样拿到的$fullUrl就是类似https://www.example.com/path?query=1的完整地址,注意HTTPS的判断不能只检查非空,因为有些服务器下HTTPS的值可能是off

端口带不带?什么时候必须带上?

本地开发经常用localhost:80800.0.1:8000,此时

PHP取域名怎么做?php获取当前域名函数详解

HTTP_HOST的值就是带端口的,如果你只是取域名用来展示,去掉端口更干净,但如果是生成API回调地址,端口必须原样保留,否则回调就跑到80端口去了。

保留端口的写法

$domainWithPort = $_SERVER['HTTP_HOST'];

去掉端口的写法

$domain = strtok($_SERVER['HTTP_HOST'], ':');

strtok比正则速度更快,一行解决。

PHP取子域名并替换顶级域名:实际业务场景怎么写?

很多站点有PC端和手机端的域名区分,比如www.example.comm.example.com,用户访问手机版时要跳转到对应子域名,这就涉及到从完整域名中提取子域名、甚至替换域名主体。

提取子域名

$host = $_SERVER['HTTP_HOST'];
// 去掉端口
$host = strtok($host, ':');
// 将域名拆分为数组
$parts = explode('.', $host);
// 如果数组长度大于2,则第一个元素是子域名(不考虑多级子域名情况)
$subdomain = (count($parts) > 2) ? $parts[0] : null;

比如m.example.com会拆成['m', 'example', 'com'],子域名就是m,但你要处理www.example.co.uk这类多段后缀,上面的逻辑就会出错,稳妥的办法是用一个公共后缀列表(Public Suffix List)来判断,但那种做法对普通网站来说太重了,多数情况下我们只需要处理常见的.com.cn.net

替换顶级域名:假设你要把www.example.com改成www.example.net,不能直接str_replace('.com', '.net'),万一域名里其他地方也有.com字符串呢?正确做法是只替换最后一段:

$host = 'www.example.com';
$pos = strrpos($host, '.'); // 找到最后一个点
$newHost = substr($host, 0, $pos) . '.net'; // 前缀保持不变

这种写法对www.example.com.cn这样的域名同样有效,因为它替换的是最后的.cn段。

处理主域名与二级域名的逻辑

取主域名(不带www和子域名)是PHP中常见的需求,尤其是做Cookie跨域共享或单点登录时,网上流传的很多正则表达式看着很吓人,其实核心就两步:

  1. 省略www
  2. 去掉端口
function getMainDomain($host) {
    $host = strtolower($host);
    $host = preg_replace('/:d+$/', '', $host);
    // 移除 www 前缀(如果有)
    if (substr($host, 0, 4) === 'www.') {
        $host = substr($host, 4);
    }
    return $host;
}

注意这个函数不处理m.example.com,它会返回m.example.com,如果你想把m也去掉,就需要额外判断,但主域名到底是指根域名还是二级域名,取决于你的业务定义

PHP取域名怎么做?php获取当前域名函数详解

,有的网站把.com.cn视为有效宿主,有的则把example.com.cn视为根域名,没有统一标准。

通过URL函数反向解析域名:parse_url的妙用

parse_url()是PHP内置的URL解析函数,它可以把一个完整URL拆成数组,如果你手里已经有一个URL字符串,想拿到里面的域名,用它是最稳的。

$url = 'https://user:pass@www.example.com:8080/path?arg=1#fragment';
$parts = parse_url($url);
$domain = $parts['host']; // 输出 www.example.com

parse_url返回的数组里host是不带端口和协议的,但注意它对中文域名和特殊字符可能处理不友好,遇到https://例子.测试这样的国际化域名,建议先idn_to_ascii()转换再解析。

从referer里取来源域名

做流量统计时经常要解析用户是从哪个网站跳转过来的,此时先拿$_SERVER['HTTP_REFERER'],再用parse_url取host:

$referer = $_SERVER['HTTP_REFERER'] ?? '';
$refererDomain = $referer ? parse_url($referer, PHP_URL_HOST) : '';

这种写法适用于统计外链来源,但提醒一句,HTTP_REFERER是浏览器提供的,可以被伪装,千万别拿它当安全判断依据。

兼容HTTPS与多域名的完整封装函数

把前面的知识串起来,封装成一个函数,这个函数满足日常95%的需求:返回当前请求的协议、域名、端口和完整URL。

function getCurrentUrlInfo() {
    // 协议
    $https = !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off';
    $scheme = $https ? 'https' : 'http';
    // 主机(含端口)
    $hostWithPort = $_SERVER['HTTP_HOST'] ?? $_SERVER['SERVER_NAME'];
    // 分离主机和端口
    $host = strtok($hostWithPort, ':');
    $port = strtok(':') ?? ($https ? '443' : '80');
    return [
        'scheme' => $scheme,
        'host' => $host,
        'port' => $port,
        'host_with_port' => $hostWithPort,
        'full_url' => $scheme . '://' . $hostWithPort . ($_SERVER['REQUEST_URI'] ?? ''),
    ];
}

怎么用?比如你在做API签名校验,需要判断回调域名是否在白名单里:

$info = getCurrentUrlInfo();
$allowedDomains = ['www.example.com', 'api.example.com'];
if (!in_array($info['host'], $allowedDomains)) {
    // 拒绝访问
}

PHP取域名时常见的5个坑

先说结论:没有完美的全局变量,只有适合场景的取舍

  • HTTP_HOST受客户端伪造影响,但它代表用户实际请求的域名,如果你要根据不同域名输出不同内容,用它是准确的。
  • SERVER_NAME由服务器配置决定,相对稳定,但可能和用户实际请求不一致(比如配置了多个虚拟主机)。
  • PHP取域名怎么做?php获取当前域名函数详解

  • 使用了CDN或反向代理时,$_SERVER['HTTP_HOST']可能是源站域名,也可能被回源请求覆盖,此时通常需要读取X-Forwarded-Host头,但要谨慎使用,因为在某些配置下该头会被客户端伪造。
  • 命令行CLI模式下所有$_SERVER相关变量都不存在,测代码时别用php cli.php直接测,得用内置服务器或配个虚拟主机。
  • 如果站点部署在负载均衡后面,$_SERVER['HTTPS']可能永远为空,因为外部SSL在LB层就结束了,此时需要看$_SERVER['HTTP_X_FORWARDED_PROTO']是否为https

PHP取域名代码的实战测试:用内置服务器模拟

不用上服务器,本地就能验证代码,打开终端进入项目目录,执行:

php -S localhost:8080

然后写个test.php

<?php
echo $_SERVER['HTTP_HOST']; // 输出 localhost:8080
echo PHP_EOL;
echo strtok($_SERVER['HTTP_HOST'], ':'); // 输出 localhost

还可以用curl -H "Host: test.example.com" http://localhost:8080/test.php来模拟Host头注入,你会发现这时HTTP_HOST变成了test.example.com,但SERVER_NAME还是localhost,这就是两者区别的最直观演示。

PHP取域名最佳实践总结

多数情况下我推荐用HTTP_HOST作为主数据源,SERVER_NAME作为兜底,取纯域名时一定要去掉端口,如果是生成链接用来重定向,保留完整Host即可,记住一点:域名获取没有银弹,取决于你是在处理HTTP业务,还是在处理服务器配置

常见问题:PHP取域名相关问答

为什么$_SERVER['HTTP_HOST']有时候拿不到值?

在命令行模式下运行PHP脚本时,没有HTTP请求,自然不会有HTTP_HOST,另外某些PHP配置(如variables_order不包含S)也会导致$_SERVER为空,脚本最好加上来容错。

$_SERVER['SERVER_NAME']HTTP_HOST选哪一个?

如果你做的是前台展示业务,选HTTP_HOST,因为它反映用户输入的域名,如果是后台判断服务器身份,选SERVER_NAME,业内专家指出,多数PHP框架(如Laravel、ThinkPHP)在生成URL时默认优先使用HTTP_HOST,这已经形成了行业共识。

如何用PHP获取当前页面的三级域名?

先把Host取出来去掉端口,然后按点拆分成数组,如果数组元素个数大于3,那么$parts[0]就是三级域名,比如a.b.example.com拆完是['a','b','example','com']$parts[0]a$parts[1]b,注意国内部分地区的运营商可能给网站加跳转页,实际生产环境取到三级域名的概率很低,别在这个功能上过度设计。

图片来源于AI模型,如侵权请联系管理员。作者:酷小编,如若转载,请注明出处:https://www.kufanyun.com/ask/776108.html

(0)
上一篇 2026年9月3日 10:20
下一篇 2026年9月3日 10:22

相关推荐

  • 域名后缀cm值得注册吗?,cm域名对网站GEO有帮助吗?

    .cm域名是喀麦隆国家顶级域名,因其与.com高度相似,常被用作“错别字流量”或品牌保护,但注册前需考虑政策限制、访问稳定性及国内备案难题,.cm域名是什么?深入了解这个“错位”的顶级域名.cm是喀麦隆(Cameroon)的国家顶级域名,由喀麦隆电信公司(Camtel)管理,它在互联网圈内被频繁讨论,主要是因为……

    2026年8月25日
    0451
  • 域名备案加急多少钱?域名备案加急最快几天下来

    域名备案加急的费用通常在600元至2000元不等,具体价格取决于加急的时效要求、备案所在省份的管局审核速度以及服务商的渠道能力,核心结论是:加急备案并非官方收费项目,而是服务商提供的增值服务,选择具备专业资质和独家渠道的服务商,是实现“极速下号”的关键,切勿轻信低价陷阱导致备案失败或信息泄露,域名备案加急的费用……

    2026年3月12日
    02381
    • 服务器间歇性无响应是什么原因?如何排查解决?

      根源分析、排查逻辑与解决方案服务器间歇性无响应是IT运维中常见的复杂问题,指服务器在特定场景下(如高并发时段、特定操作触发时)出现短暂无响应、延迟或服务中断,而非持续性的宕机,这类问题对业务连续性、用户体验和系统稳定性构成直接威胁,需结合多维度因素深入排查与解决,常见原因分析:从硬件到软件的多维溯源服务器间歇性……

      2026年1月10日
      020
  • tomcat 二级域名

    Tomcat与二级域名结合部署是通过虚拟主机机制实现多站点隔离与路径分发的标准方案,2026年行业推荐采用反向代理+Tomcat实例或单实例多Host配置,前者更适合高并发与安全隔离场景,Tomcat二级域名配置的核心原理虚拟主机模型在Tomcat中的实现Tomcat的虚拟主机能力基于server.xml中的……

    2026年8月3日
    0581
  • 安阳域名怎么注册?安阳域名注册流程及费用详解

    安阳域名注册与运营在 2026 年已全面进入“本地化品牌资产化”阶段,核心结论是:企业应优先布局含“安阳”地域词的二级或三级域名,并结合国家信创标准进行备案,以获取本地搜索加权及政府项目准入资格,在 2026 年数字经济深水区,域名不再仅仅是网址入口,而是安阳地区企业构建数字信任的基石,随着“数字安阳”战略的推……

    2026年5月4日
    01753

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注