一、前言
在PHP开发中,获取当前域名是一个常见的需求,比如用于生成完整URL、判断当前环境、做域名授权验证、记录来源信息等。本文将总结多种PHP获取当前域名的方法,包括获取主域名、顶级域名、完整URL路径、端口等实用技巧。
主要获取主域名,自动识别证书,例如:https://www.csdn.net/,可以当作普通函数使用,或者在框架中添加函数使用。
二、获取当前域名(自动识别HTTPS)
这是最常用的方法,可以自动判断当前是HTTP还是HTTPS协议:
<?php
function getHostDomain()
{
return getHttpType() . $_SERVER['SERVER_NAME'];
}
/**
* 获取 HTTPS协议类型
* @return string
*/
function getHttpType()
{
return $type = ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') || (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')) ? 'https://' : 'http://';
}
// 使用示例
echo getHostDomain(); // 输出:https://www.example.com
说明:
$_SERVER['HTTPS']:判断是否启用了HTTPS$_SERVER['HTTP_X_FORWARDED_PROTO']:用于反向代理(如Nginx代理)场景下判断协议$_SERVER['SERVER_NAME']:获取服务器域名(不含端口号)
三、$_SERVER变量获取域名相关
PHP的$_SERVER超全局变量包含了大量服务器和环境信息,以下是获取域名相关的常用键值:
<?php
// 获取当前域名(不含端口号)
echo $_SERVER['SERVER_NAME']; // www.example.com
// 获取当前域名(含端口号)
echo $_SERVER['HTTP_HOST']; // www.example.com:8080
// 获取当前请求URI
echo $_SERVER['REQUEST_URI']; // /index.php?id=123
// 获取当前完整URL
$protocol = ((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
$url = $protocol . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
echo $url; // https://www.example.com/index.php?id=123
四、获取完整URL(包含路径和参数)
有时候我们需要获取包含路径和参数的完整URL:
<?php
/**
* 获取当前页面完整URL
* @return string
*/
function getFullUrl()
{
$protocol = isHttps() ? 'https://' : 'http://';
return $protocol . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
}
/**
* 判断是否为HTTPS
* @return bool
*/
function isHttps()
{
if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') {
return true;
}
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') {
return true;
}
if ($_SERVER['SERVER_PORT'] == 443) {
return true;
}
return false;
}
// 使用示例
echo getFullUrl();
五、获取域名的各个部分
通过parse_url函数可以解析URL的各个组成部分:
<?php
$url = 'https://www.example.com:8080/path/page.html?id=123#anchor';
$parts = parse_url($url);
print_r($parts);
// 输出结果:
// Array
// (
// [scheme] => https // 协议
// [host] => www.example.com // 域名
// [port] => 8080 // 端口
// [path] => /path/page.html // 路径
// [query] => id=123 // 查询参数
// [fragment] => anchor // 锚点
// )
// 获取域名
echo $parts['host']; // www.example.com
// 获取端口
echo $parts['port']; // 8080
六、获取主域名(根域名)
从完整域名中提取主域名(如从www.example.com获取example.com):
<?php
/**
* 获取主域名(根域名)
* @param string $domain 完整域名
* @return string
*/
function getMainDomain($domain)
{
// 定义顶级域名列表
$tlds = [
'com.cn', 'net.cn', 'org.cn', 'gov.cn', 'co.uk', 'co.jp',
'com.tw', 'com.hk', 'com.ru', 'net.tw', 'net.hk'
];
// 分割域名
$parts = explode('.', $domain);
$count = count($parts);
// 检查是否是带国别后缀的顶级域名
$lastTwo = $parts[$count-2] . '.' . $parts[$count-1];
if (in_array($lastTwo, $tlds)) {
// 如 xxx.com.cn 返回倒数第三部分+倒数第二部分+最后一部分
return $parts[$count-3] . '.' . $lastTwo;
}
// 普通情况返回后两部分
return $parts[$count-2] . '.' . $parts[$count-1];
}
// 使用示例
echo getMainDomain('www.example.com'); // example.com
echo getMainDomain('blog.example.com.cn'); // example.com.cn
echo getMainDomain('www.csdn.net'); // csdn.net
七、获取二级域名前缀
获取域名的子域名部分:
<?php
/**
* 获取二级域名前缀
* @return string
*/
function getSubDomain()
{
$host = $_SERVER['HTTP_HOST']; // www.example.com
$parts = explode('.', $host);
if (count($parts) >= 3) {
return $parts[0]; // www
}
return '';
}
// 使用示例
echo getSubDomain(); // 如 www.example.com 返回 www
八、获取当前域名端口
<?php
/**
* 获取当前域名端口
* @return int|string
*/
function getDomainPort()
{
return $_SERVER['SERVER_PORT']; // 80 或 443
}
// 获取端口号
echo getDomainPort();
九、获取顶级域名
从域名中提取顶级域名部分:
<?php
/**
* 获取顶级域名(如 .com, .cn, .net)
* @param string $domain
* @return string
*/
function getTopLevelDomain($domain)
{
$parts = explode('.', $domain);
return end($parts);
}
// 使用示例
echo getTopLevelDomain('www.example.com'); // com
echo getTopLevelDomain('www.example.cn'); // cn
echo getTopLevelDomain('www.example.org'); // org
十、常用场景汇总
场景1:判断当前是否为HTTPS
<?php
function checkHttps()
{
if ((isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) !== 'off')
|| (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https')
|| (isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] == 443)) {
return true;
}
return false;
}
场景2:获取域名的多种写法汇总
<?php
// 获取协议+域名
$domain = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https://' : 'http://') . $_SERVER['HTTP_HOST'];
echo $domain; // https://www.example.com
// 获取域名(不含www)
$host = $_SERVER['HTTP_HOST'];
$domainNoWww = preg_replace('/^www\./', '', $host);
echo $domainNoWww; // example.com
// 获取完整URL含参数
$fullUrl = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https://' : 'http://')
. $_SERVER['HTTP_HOST']
. $_SERVER['REQUEST_URI'];
echo $fullUrl; // https://www.example.com/page?id=1
场景3:Laravel框架中获取域名
<?php
// Laravel中获取当前URL
url()->current(); // 当前URL(不含参数)
url()->full(); // 完整URL(含参数)
url()->previous(); // 上一页URL
// 获取域名
request()->getHost(); // www.example.com
request()->getHttpHost(); // www.example.com:8080
request()->root(); // https://www.example.com
// 判断HTTPS
request()->secure(); // true 或 false
十一、注意事项
- 安全性:
$_SERVER['HTTP_HOST']来自HTTP请求头,可能被伪造,不要用于安全敏感场景 - 反向代理:使用了Nginx等反向代理时,需要通过
HTTP_X_FORWARDED_PROTO判断真实协议 - 端口问题:
SERVER_NAME不含端口,HTTP_HOST包含端口号 - 框架使用:在Laravel、ThinkPHP等框架中,建议使用框架提供的方法获取
十二、完整工具函数
<?php
/**
* 域名获取工具类
*/
class DomainHelper
{
/**
* 获取当前完整URL
*/
public static function fullUrl()
{
return self::scheme() . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
}
/**
* 获取当前域名(不含路径)
*/
public static function domain()
{
return self::scheme() . $_SERVER['HTTP_HOST'];
}
/**
* 获取主域名
*/
public static function mainDomain()
{
$host = explode(':', $_SERVER['HTTP_HOST'])[0];
$parts = explode('.', $host);
$count = count($parts);
if ($count <= 2) {
return $host;
}
return $parts[$count-2] . '.' . $parts[$count-1];
}
/**
* 获取协议
*/
public static function scheme()
{
if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') {
return 'https://';
}
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') {
return 'https://';
}
if (isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] == 443) {
return 'https://';
}
return 'http://';
}
/**
* 判断是否为HTTPS
*/
public static function isHttps()
{
return self::scheme() === 'https://';
}
}
// 使用示例
echo DomainHelper::fullUrl(); // https://www.example.com/page?id=1
echo DomainHelper::domain(); // https://www.example.com
echo DomainHelper::mainDomain(); // example.com
echo DomainHelper::isHttps() ? '是HTTPS' : '是HTTP';
总结
本文详细介绍了PHP获取当前域名的多种方法,从简单的$_SERVER变量获取,到自动识别HTTPS协议,再到提取主域名、二级域名等高级用法。在实际开发中,建议根据具体需求选择合适的方法,并封装成统一的工具函数便于复用。
对于在生产环境使用,建议:
- 使用框架提供的方法(如Laravel的Request对象)
- 封装统一的工具函数
- 考虑反向代理场景的协议判断
- 不要直接信任用户传入的域名信息

发表评论 取消回复