phpenv 不处理二级域名或泛解析,它仅提供 PHP 版本管理;本地泛域名需三者协同:dnsmasq 或 hosts(DNS 层)、Nginx 泛域名 server_name(Web 层)、PHP 安全解析 HTTP_HOST(应用层)。

phpenv 本身不处理二级域名或泛解析,它只是 PHP 版本管理工具,和 Web 服务器、DNS 完全无关。 你真正需要的是在本地开发环境(比如用 nginx 或 apache + php-fpm)中模拟泛域名行为,并让系统能解析 *.test 这类域名 —— phpenv 在这个链条里只负责提供对应版本的 php 可执行文件,其余一概不管。
为什么 phpenv 配置不了二级域名
它不启动 Web 服务,不读取 server_name,也不参与 HTTP 请求路由。你看到的“本地泛域名”效果,实际来自:dnsmasq / etc/hosts(DNS 层)、nginx 的 server_name ~^([^.]+)\.test$(Web 层)、以及 PHP 中对 $_SERVER['HTTP_HOST'] 的解析(应用层)。phpenv 只在最后一步被调用:当 Nginx 把请求交给 php-fpm 时,后者用的是 phpenv 切换出来的那个 PHP 版本。
本地泛域名解析必须做的三件事
缺一不可,否则浏览器打不开 foo.test:
- 在
/etc/hosts中加一行:127.0.0.1 foo.test bar.test *.test—— 注意:通配符*在 hosts 文件中无效,只能逐条写,或改用dnsmasq - 用
dnsmasq实现真泛解析:配置address=/.test/127.0.0.1,然后sudo brew services restart dnsmasq(macOS)或sudo systemctl restart dnsmasq(Linux) - Nginx 必须监听泛域名:
server_name ~^([^.]+)\.test$;,并确保root指向统一入口(如/var/www/html/index.php),否则 404
PHP 中安全提取子域名的写法
别直接用 explode('.', $_SERVER['HTTP_HOST'])[0] —— 它在 www.test、api.test、test 场景下会出错。推荐用这个函数:
立即学习“PHP免费学习笔记(深入)”;
function getSubdomain($host = null, $mainDomain = 'test') {
$host = $host ?: $_SERVER['HTTP_HOST'];
if (strpos($host, ':') !== false) {
$host = strstr($host, ':', true);
}
if (preg_match('/^([^.]+)\.' . preg_quote($mainDomain, '/') . '$/', $host, $m)) {
return $m[1];
}
return null;
}
返回 foo(当访问 foo.test),返回 null(当访问 test 或 www.test),你可以根据业务决定是否把 www 当作特殊子域处理。
容易被忽略的关键点
Nginx 的 fastcgi_param SCRIPT_FILENAME 必须用 $document_root$fastcgi_script_name,而不是硬编码路径;否则泛域名下所有 PHP 请求都会报 No input file specified。另外,php-fpm 的 user 和 group 必须对你的项目目录有读取权限 —— 这个错误在切换 phpenv 版本后常被误认为是 PHP 问题,其实是权限没同步更新。



















