多站点共用一个ip时,thinkphp伪静态必须通过服务器层显式隔离:apache需为每个域名配置独立virtualhost及documentroot指向对应public目录,nginx需为每个域名设置独立server块并配root和try_files;框架内须开启url_domain_deploy并用route::domain()分组定义路由,否则请求错进其他站点index.php导致404或路由混用。

多站点共用一个 IP 时,ThinkPHP 伪静态不能靠“写一套规则通用所有域名”,必须按域名或子域名做显式隔离——否则请求会错进其他站点的 index.php,轻则 404,重则路由混用、参数污染。
Apache 下用 VirtualHost + DocumentRoot 区分主站与子域名
同一 IP 上跑 www.example.com 和 admin.example.com,不能只靠 .htaccess 分流。关键在虚拟主机配置:
- 每个
<virtualhost></virtualhost>块必须指定独立的DocumentRoot,指向对应项目的public/目录(哪怕物理路径相同,也要显式写明) -
ServerName和ServerAlias必须精确匹配,比如ServerName admin.example.com,避免泛域名覆盖导致请求被错误捕获 -
.htaccess文件可以共用,但前提是它放在各自DocumentRoot下(即每个站点的public/目录里各有一份) - 若共用代码库,
AllowOverride必须设为FileInfo Options,而不是All,否则某些 Apache 发行版会拒绝加载 rewrite 模块
Nginx 中必须为每个 server 块单独配 try_files
Nginx 不像 Apache 那样能靠 .htaccess 动态生效,所有分流逻辑必须写死在 server 块里:
- 每个域名(包括
www和裸域)都得有独立的server块,哪怕监听同一 IP+端口 -
root指令必须指向该站点的public/目录,例如root /var/www/admin/public; - 伪静态核心是这行:
try_files $uri $uri/ /index.php?s=$uri&$args;—— 注意&是 HTML 实体,不能写成&,否则nginx -t会报错 - HTTPS 站点必须另起一个
server { listen 443 ssl; ... },且里面的try_files规则要完全一致,不能复用 HTTP 块里的配置
ThinkPHP 内部要用 Route::domain() 划清路由边界
服务器层分流只是第一步,框架内不隔离,admin.example.com/user 还是可能被主站路由捕获:
- 必须开启
url_domain_deploy,在config/app.php中设为true - 路由定义改用
Route::domain()分组,例如:Route::domain('admin.example.com', function () { Route::get('user/list', 'admin.User/index'); }); - 不要依赖
$_SERVER['HTTP_HOST']手动判断——TP6 的Route::domain()会在路由解析早期就截断非匹配域名的请求,性能更好也更安全 - 如果用了多语言,
__lang__变量必须在域名路由分组内注册,否则语言切换链接会生成错误的 host
最容易被忽略的是:Nginx 的 server_name 匹配是严格区分大小写的,而浏览器发来的 Host 头可能是小写;Apache 的 ServerName 虽然不敏感,但 ServerAlias 如果漏写 www. 前缀,就会导致带 www 的请求落到默认虚拟主机里——此时伪静态规则看似生效,实际却进了另一个项目的 index.php。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











