多子域名共享应用文件的.htaccess路由配置问题求助
解决子域名路由到核心应用目录的问题
看起来你想实现的是多子域名共享同一应用核心文件,同时保留子域名URL来切换数据库,主域名domain.com用独立文件,app.domain.com存核心代码。之前的.htaccess配置没抓住要点,我来帮你一步步搞定:
第一步:确认基础配置前提
在折腾.htaccess之前,必须先搞定这两个关键配置:
- DNS解析:把
sub1.domain.com、sub2.domain.com等所有需要的子域名,和app.domain.com一起解析到同一服务器IP。 - 文件权限与目录结构:确保Apache服务器有权限访问
app.domain.com的核心文件目录,比如你的目录结构可能是这样:/var/www/ ├── domain.com/ # 主域名独立文件 └── app.domain.com/ # 应用核心文件
第二步:正确的.htaccess配置(分两种场景)
场景1:你有权修改Apache虚拟主机配置(推荐)
这是最稳定的方案,不需要复杂的.htacess规则:
- 为所有子域名创建虚拟主机配置,把它们的
DocumentRoot指向app.domain.com的核心目录:<VirtualHost *:80> ServerName sub1.domain.com ServerAlias sub2.domain.com *.domain.com # 匹配所有子域名 DocumentRoot /var/www/app.domain.com/ <Directory /var/www/app.domain.com/> AllowOverride All Require all granted </Directory> </VirtualHost> # 主域名的独立虚拟主机 <VirtualHost *:80> ServerName domain.com ServerAlias www.domain.com DocumentRoot /var/www/domain.com/ <Directory /var/www/domain.com/> AllowOverride All Require all granted </Directory> </VirtualHost> - 这样所有子域名请求会直接加载核心应用文件,URL保持不变,完全不需要额外的.htaccess规则。
场景2:只能用.htaccess(无虚拟主机修改权限)
如果只能通过.htaccess实现,需要借助反向代理或者内部重写:
方案A:反向代理(URL不变,推荐)
在每个子域名的根目录(比如/var/www/sub1.domain.com/)创建.htaccess,写入以下规则:
Options +FollowSymLinks -MultiViews RewriteEngine On # 排除主域名和www,只处理子域名 RewriteCond %{HTTP_HOST} !^(www\.)?domain\.com$ [NC] # 匹配任意子域名 RewriteCond %{HTTP_HOST} ^([a-z0-9-]+)\.domain\.com$ [NC] # 反向代理请求到app.domain.com,保持URL不变 RewriteRule ^(.*)$ http://app.domain.com/$1 [P,L]
注意:需要确保Apache启用了
mod_proxy和mod_proxy_http模块,否则会报错。
方案B:内部文件重写(同一服务器目录)
如果app.domain.com和子域名的目录在同一服务器,可以直接重写文件路径,不需要代理:
Options +FollowSymLinks -MultiViews RewriteEngine On RewriteBase / # 匹配子域名 RewriteCond %{HTTP_HOST} !^(www\.)?domain\.com$ [NC] RewriteCond %{HTTP_HOST} ^([a-z0-9-]+)\.domain\.com$ [NC] # 内部重写请求到核心应用目录(替换成你实际的绝对路径) RewriteRule ^(.*)$ /var/www/app.domain.com/$1 [L]
第三步:应用中切换数据库
在你的PHP应用中,通过获取当前子域名来切换数据库:
// 获取当前子域名 $host = $_SERVER['HTTP_HOST']; $subdomain = explode('.', $host)[0]; // 根据子域名选择数据库配置 switch($subdomain) { case 'sub1': $dbConfig = ['host' => 'localhost', 'dbname' => 'db_sub1', ...]; break; case 'sub2': $dbConfig = ['host' => 'localhost', 'dbname' => 'db_sub2', ...]; break; // 其他子域名逻辑 default: // 默认配置或错误处理 break; }
为什么之前的配置失败?
- 第一个规则里的
^../app(.*)$是错误的:RewriteRule的匹配是基于当前目录的URL路径,不能用../来跨目录,Apache会拒绝这种写法。 - 第二个规则是把主域名请求转到指定文件夹,和你的需求完全相反,自然无法实现子域名路由。
内容的提问来源于stack exchange,提问作者Dennis
相关产品推荐
相关产品推荐

