PHP本身不参与多站点路由,关键在Web服务器配置和PHP-FPM隔离;Apache需独立VirtualHost、Nginx需精确server_name与root匹配,PHP-FPM必须为每站配置独立池及专属用户。

PHP 本身不参与多站点路由决策,最新版(如 PHP 8.3/8.4)和旧版在多站点部署上没有本质区别——关键在 Web 服务器配置和 PHP-FPM 隔离,不是升级 PHP 就能“自动支持多站点”。
Apache 的 VirtualHost 必须显式启用且每个站点独占一个块
即使用了 PHP 8.4,httpd.conf 里若没取消注释 Include conf/extra/httpd-vhosts.conf,所有 <virtualhost></virtualhost> 都不会生效。常见错误是把多个 ServerName 塞进同一个 <virtualhost></virtualhost> 块里,结果只有第一个域名被识别。
-
DocumentRoot路径末尾不能带斜杠(/var/www/site-a/❌ →/var/www/site-a✅) - 每个
<virtualhost></virtualhost>必须配独立的<directory></directory>段,且含Require all granted,否则 403 Forbidden -
ServerName必须写完整域名(site-a.local),不能只写site-a;开发时用.local后缀比.dev更稳妥(避免浏览器 HSTS 强制 HTTPS) - 改完必须
sudo systemctl reload apache2,restart会中断正在处理的请求
Nginx 的 server_name 和 root 必须精确匹配请求头与文件系统
PHP 版本再新,server_name site-a.com 若没在 DNS 或 /etc/hosts 中解析到本机,Nginx 根本收不到该请求;更常见的是 root 指向了父目录(如 /var/www),导致所有站点都 fallback 到默认页面或 404。
-
index必须显式包含index.php(index index.php index.html;),否则 .php 文件不会被当作入口 -
location ~ \.php$块里的fastcgi_param SCRIPT_FILENAME推荐用$document_root$fastcgi_script_name,硬编码路径极易出错 - 测试配置前先跑
sudo nginx -t,语法错会导致整个 Nginx 拒绝加载 - HTTPS 站点必须为每个域名单独配
ssl_certificate,共用证书会导致 SNI 不匹配或浏览器警告
PHP-FPM 池隔离不是可选项,而是防止“一崩全崩”的底线
PHP 8.3+ 默认仍用 www 池,但多个站点共用它等于把鸡蛋放在一个篮子里:某个站死循环、内存泄漏或慢日志刷爆磁盘,其他站立刻 502 Bad Gateway。这不是 PHP 版本问题,是配置缺失。
立即学习“PHP免费学习笔记(深入)”;
- 每个高流量或第三方代码站点,必须建独立池,例如
/etc/php/8.3/fpm/pool.d/site-a.conf - 池内
user/group应设为专属系统用户(site-a-user),不能全用www-data -
listen必须用 Unix socket(/run/php/php8.3-fpm-site-a.sock),比 TCP 端口更安全、更快 - 改完要
sudo systemctl reload php8.3-fpm,不是 restart —— reload 会平滑切换子进程
最容易被忽略的是环境变量注入和静态资源路径:PHP 代码里用 $_SERVER['HTTP_HOST'] 做站点判断时,必须 strtolower() + 清除端口;而 CSS/JS 中的相对路径(如 ../images/logo.png)在不同 DocumentRoot 下会失效,得统一用绝对路径或通过 base 标签修正。



















