最可靠方式是用 parse_url($url, PHP_URL_HOST) 提取 host,再按需处理子域、IDN 和 IPv6;避免正则或 str_replace 硬切,注意反向代理下优先用 $_SERVER[‘SERVER_NAME’]。
PHP中用 parse_url() 提取主域名最可靠
直接用 $_SERVER['HTTP_HOST'] 或 $_SERVER['SERVER_NAME'] 拿到的只是主机名(如 example.com 或 www.example.com),但如果你手头是一个完整 URL 字符串(比如 "https://blog.example.com:8080/path/to/page?x=1#section"),必须先解析再剥离路径。此时 parse_url() 是唯一推荐方式,它能准确分离 scheme、host、port、path、query、fragment。
常见错误是用 str_replace() 或正则硬切,结果在带端口、子域、IPv6 地址(如 [::1])或特殊字符时直接崩。
-
parse_url($url, PHP_URL_HOST)返回 host 部分,不含端口(如blog.example.com) - 若需保留端口,用
parse_url($url, PHP_URL_PORT)单独获取,再手动拼接 - 注意:
PHP_URL_HOST对 IPv6 地址会返回带方括号的格式([2001:db8::1]),这是合规行为,别误判为异常
去掉 www 前缀但不误伤其他子域?用条件判断别硬删
很多方案直接 str_replace('www.', '', $host),这会导致 www-admin.example.com 变成 admin.example.com,完全错误。正确做法是明确判断 host 是否以 www. 开头且长度刚好比 www. 多出一个合法域名长度(即后面至少含一个点 + 二级域)。
- 安全写法:
if (substr($host, 0, 4) === 'www.' && strpos($host, '.', 4) !== false) { $host = substr($host, 4); } - 更健壮可配合
filter_var($host, FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME)验证剥离后的合法性(PHP 7.4+) - 别用
preg_replace('/^www\./', '', $host)—— 没加锚定边界,可能误替换路径里的 www
从 $_SERVER 获取当前请求主域要注意协议和重写影响
如果目标只是当前页面的主域名(非任意 URL),不要自己拼 $_SERVER['HTTP_HOST'] 和 $_SERVER['HTTPS'],因为反向代理(如 Nginx + Apache)下 HTTP_HOST 可能被篡改,HTTPS 环境变量也可能缺失或值为 off。