php网站子域名处理依赖dns配置、web服务器分发和php应用层识别三层协作:dns需泛解析(a记录设指向ip),nginx配server_name .example.com,apache启mod_vhost_alias并设serveralias .example.com;本地开发需在hosts逐行添加子域名;php层通过$_server['http_host']或thinkphp的route::domain('')结合request()->subdomain()识别路由;多租户推荐共用代码库+动态加载配置,避免nginx重写硬映射。

PHP网站本身不直接解析域名,子域名和泛域名的处理依赖于DNS配置 + Web服务器分发 + PHP应用层识别三层协作。关键不是“PHP怎么做”,而是怎么让请求准确到达PHP,并让PHP代码知道当前访问的是哪个子域名。
DNS与服务器层:先让请求进来
没有这一步,PHP根本收不到请求。
- DNS必须配置泛解析(A记录主机名填
*,指向服务器IP),否则a.example.com连服务器都找不到 - Nginx需在server块中写
server_name *.example.com;;Apache需启用mod_vhost_alias并配置ServerAlias *.example.com - 本地开发时,hosts文件必须逐行添加:
127.0.0.1 a.example.com、127.0.0.1 b.example.com——*.example.com在hosts里无效 - 宝塔、phpStudy等面板添加站点时,域名栏填
*.example.com是让Web服务器接收所有子域请求,不是自动建站
PHP应用层:识别并路由子域名
Web服务器把请求转给PHP后,得靠代码判断来源并分发逻辑。
- ThinkPHP用
Route::domain('*')包裹路由,并在闭包内调用request()->subDomain()提取子域名字符串 - Phpcms通过后台“站点管理”绑定域名,运行时根据
$_SERVER['HTTP_HOST']匹配站点ID - 自定义框架可统一读取
$_SERVER['HTTP_HOST'],用explode('.', $host)拆解,再按规则映射到目录或数据库租户 - 不能依赖
APP_SUB_DOMAIN_DEPLOY等旧配置自动跳转——ThinkPHP 6+已移除该自动绑定机制
多站点物理隔离与共享策略
多个子站共用一套代码还是各自独立,影响部署方式。
- 若各子站完全独立(如不同客户后台),建议每个子域名对应独立网站目录+独立PHP-FPM池,提升安全与资源隔离
- 若为SaaS或多租户模式(共用代码库),根目录统一,靠子域名动态加载配置、模板、数据库连接
- Phpcms、帝国CMS等系统支持“站点ID”机制,通过
define('SITEID', 2)在子目录入口中指定归属 - 避免用Nginx重写把
a.example.com强行映射到/a/子目录——路径硬编码会限制扩展性,优先走应用层路由
常见失效原因与排查顺序
90%的问题出在这四步链路上,按顺序检查:
- dig a.example.com确认DNS是否返回正确IP(非本地缓存)
- curl -H "Host: a.example.com" http://127.0.0.1 查看能否拿到预期响应(排除DNS与网络问题)
- 查看Web服务器error.log,确认请求是否被正确路由到目标server块
- 在PHP入口加
var_dump($_SERVER['HTTP_HOST']); die();,验证子域名是否传入
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











