服务器与大带宽专家 · 持牌IDC/CDN/ISP服务商
简米科技官网JIANMI TECH
资讯 2026-10-21 简米科技 4,253 字 10 分钟阅读

TP5如何获取当前网站完整域名带端口?,tp5怎么获取端口

导读TP5获取当前网站完整域名带端口,优先用Request::instance()->domain()拿到“协议+Host”,再用SERVER_PORT或X-Forwarded-Port补全端口;在反向代理和HTTPS环境里,单靠SERVER_NAME往往会丢端口, 下面按可直接复制的代码、常见场景和排查路径……

TP5获取当前网站完整域名带端口,优先用Request::instance()->domain()拿到“协议+Host”,再用SERVER_PORT或X-Forwarded-Port补全端口;在反向代理和HTTPS环境里,单靠SERVER_NAME往往会丢端口。 下面按可直接复制的代码、常见场景和排查路径展开。

TP5获取当前域名带端口的方法

控制器里先拿基础值

在TP5项目中,最直接的方式是引入think\Request。domain()返回当前包含协议和域名的URL,多数情况下Host里已经带了端口,例如本地环境会得到http://localhost:8080。

use think\Request;
$request = Request::instance();
$fullDomain = $request->domain();

如果只是拼资源地址、回调地址或跳转地址,这个值可以先用,但生产环境要留意两点:反向代理可能改写Host头,HTTPS可能在代理层终止,这两点都会让domain()拿到http而不是https,或者只拿到域名没有端口。

写一个可复用的辅助函数

TP5.0可放在application/common.php,TP5.1可放在app/common.php,函数先取框架的scheme()、host()、port(),再判断Host里是否已有端口,避免重复拼接。

function current_full_domain()
{
    $request = \think\Request::instance();
    $scheme = $request->scheme();
    $host = $request->host();
    $port = (int) $request->port();
    if (!preg_match('/:\d+$/', $host) && !in_array($port, [80, 443], true)) {
        $host .= ':' . $port;
    }
    return $scheme . '://' . $host;
}

调用时直接写$url = current_full_domain();,本地localhost:8080会得到http://localhost:8080,自定义HTTPS端口8443会得到https://www.example.com:8443。80和443是默认端口,浏览器通常会省略,代码里也不必强行补上。

反向代理场景要读转发头

Nginx、CDN和负载均衡常见做法是把请求转发给PHP-FPM,此时REMOTE_ADDR和SERVER_PORT可能变成内网地址与内部端口,可以在辅助函数里优先读取X-Forwarded-Proto、X-Forwarded-Host、X-Forwarded-Port,但只应在可信代理后面使用。

function current_full_domain()
{
    $request = \think\Request::instance();
    $scheme = $request->header('x-forwarded-proto') ?: $request->scheme();
    $host = $request->header('x-forwarded-host') ?: $request->host();
    $port = (int) ($request->header('x-forwarded-port') ?: $request->port());
    if (!preg_match('/:\d+$/', $host) && !in_array($port, [80, 443], true)) {
        $host .= ':' . $port;
    }
    return $scheme . '://' . $host;
}

Nginx侧可以这样配置,宝塔面板可在“网站-设置-反向代理-配置文件”里检查:

proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port;

这里用$http_host而不是$host,是因为$host在部分配置下会丢掉非标准端口,改完后用nginx -t检查,再重载Nginx。

TP5获取当前域名带端口与Request::url区别对比

不少项目会把domain()和url(true)混着用,两者目标不同:前者偏“站点根地址”,后者偏“当前请求地址”,下面这张表按实际输出做对比。

方法或变量 示例输出 端口表现 适用场景
Request::instance()->domain() https://www.example.com:8443 通常跟随Host头,可能含端口 拼资源地址、站点根地址
Request::instance()->url(true) https://www.example.com:8443/news/1.html?id=2 跟随Host头,通常含端口 当前页面完整地址
$_SERVER['HTTP_HOST'] www.example.com:8080 通常含端口 快速取Host,但要校验
$_SERVER['SERVER_NAME'] www.example.com 通常不带端口 服务器配置名,不适合单独拼完整域名
$_SERVER['SERVER_PORT'] 8080 纯端口数字 配合协议补全端口

本地开发TP5获取当前域名带端口为什么少了端口

本地用php -S 0.0.0.0:8080或Apache虚拟主机时,浏览器访问地址是http://localhost:8080,HTTP_HOST一般会带8080,如果代码只取了SERVER_NAME,结果就是localhost,端口自然消失,另一种情况是框架或中间件里把Host固定成了配置域名,也会覆盖真实端口,排查时先打印$_SERVER['HTTP_HOST']、$_SERVER['SERVER_PORT']和$request->host(),看端口丢在哪一层,需要验证代理转发时,可以用命令模拟:

curl -H "Host: demo.com:8080" http://127.0.0.1:8080/index/index/domain

返回结果里应出现demo.com:8080,如果只出现demo.com,说明入口或代理层改写了Host。

国内服务器宝塔面板部署TP5获取完整域名带端口的检查点

国内服务器常见“Nginx+宝塔+TP5”组合,检查顺序可以按下面走:

  • 站点配置里的server_name是否只写了域名,是否漏了非标准端口。
  • 反向代理配置是否使用$http_host,是否传递了X-Forwarded-Port。
  • PHP-FPM是否收到正确的HTTP_HOST,可在控制器临时输出$request->host()。
  • 是否启用了CDN或WAF,回源端口和回源Host是否被改写。
  • HTTPS证书是否在代理层终止,若是,PHP侧要读X-Forwarded-Proto。

据PHP官方文档,HTTP_HOST来自客户端请求头,不能默认当作可信输入,业内专家指出,凡是把域名用于支付回调、密码重置链接的场景,都要对Host头做白名单校验,避免请求头被伪造后生成错误链接。

TP5获取当前域名带端口需要付费扩展吗

这类基础URL获取不需要购买付费扩展。TP5自带的Request类与$_SERVER变量已经够用,真正要投入的是代理配置、HTTPS判断和域名白名单校验,行业共识认为,付费插件更适合复杂路由、权限或后台生态,单纯取“协议+域名+端口”没必要额外引入依赖,若项目已有统一URL生成服务,把辅助函数放进公共文件或中间件即可,后续换框架也容易迁移。

收束

把流程收束成一句话:先用Request::instance()->domain()拿协议和Host,再用SERVER_PORT或X-Forwarded-Port补端口,最后做Host白名单校验,生产环境不要把HTTP_HOST直接拼进支付回调或密码重置链接。

TP5获取当前网站完整域名带端口的常见问答

TP5获取当前网站完整域名带端口时,domain()和HTTP_HOST选哪个?

看场景,只要站点根地址、且代理配置规范,用domain()更省事;需要自己控制端口补全和代理头时,用HTTP_HOST配合SERVER_PORT更透明,两者都要做Host校验。

为什么线上HTTPS获取到的是http,而且没有端口?

常见原因是HTTPS在Nginx或CDN终止,PHP侧只看到内部HTTP请求,让代理传递X-Forwarded-Proto和X-Forwarded-Port,代码里优先读这两个头,若端口是443,浏览器本来就会省略,不需要强行显示。

TP5获取当前网站完整域名带端口需要改框架源码吗?

不需要,把辅助函数放在application/common.php或app/common.php,或在中间件里统一赋值给模板即可,结论是:优先用Request::instance()->domain(),再用SERVER_PORT和代理头补全,生产环境同时做Host白名单校验。

分享本文
本文为 简米科技官网 原创,已由运维技术专家审核。转载请注明来源:原文链接
售前咨询 服务热线 售后 邮箱