symfony内置server不支持多站点,因其单进程、单端口(如8000),无法基于域名或路径虚拟主机;生产需frankenphp或nginx+php-fpm,frankenphp依赖caddyfile配置root和php_server,须注意路径、环境变量、缓存隔离及sapi适配。

为什么不能直接用 Symfony 内置 server 跑多站点
因为 php bin/console server:run 和 symfony server:start 都是单进程、单入口、绑定固定端口(如 8000)的开发服务器,不支持基于域名或路径的虚拟主机切换。生产环境必须用 FrankenPHP 或 Nginx + PHP-FPM 模式才能实现多站点隔离。
FrankenPHP 的 multi-site 配置关键在 Caddyfile
FrankenPHP 基于 Caddy,多站点靠 Caddyfile 实现反向代理与路径路由。每个 Symfony 项目需独立子域名或路径,并显式指定其 public/ 目录为 root,同时启用 PHP 处理器。
常见错误现象:404 Not Found(未命中 public/index.php)、500 Internal Server Error(未正确传递 PATH_INFO 或 SCRIPT_FILENAME)。
- 每个站点块必须包含
php_server指令,不能只写php -
root * /path/to/project/public路径必须绝对且可读,建议用$(realpath .)测试 - 若用子路径(如
/blog),需在 Symfony 中设置TRUSTED_PROXIES和TRUSTED_HOSTS,否则url()生成链接会漏掉路径前缀 - 避免在多个站点间共用
var/cache目录,否则容器编译冲突导致 500
示例片段(两个子域名):
site1.example.com {
root * /var/www/site1/public
php_server
}
<p>site2.example.com {
root * /var/www/site2/public
php_server</p><h1>若需额外环境变量(如 APP_ENV=prod)</h1><pre class="brush:php;toolbar:false;"><code>php_server env APP_ENV=prod</code>}
Symfony 项目自身要适配 FrankenPHP 的运行时环境
FrankenPHP 不是传统 CGI/FPM,它通过 SAPI 直接加载 PHP,因此部分环境检测逻辑会失效。重点调整以下几处:
-
.env中强制设APP_ENV=prod或APP_ENV=dev,不要依赖$_SERVER['APP_ENV']自动推断 -
public/index.php开头加$_SERVER['APP_ENV'] = $_ENV['APP_ENV'] ?? 'prod';避免环境误判 - 确保
APP_SECRET已设置,否则缓存无法写入(尤其var/cache/prod权限问题常被忽略) - 禁用
opcache.revalidate_freq=0(FrankenPHP 默认启用 opcache,但开发中改代码不生效时先查这个)
调试 FrankenPHP 多站点失败的三个必查点
大部分“配置写了但打不开”的问题都集中在这三处,而不是 Caddyfile 语法本身:
- 检查
systemctl status frankenphp输出里是否报failed to load site config—— 通常是 Caddyfile 缩进错误或用了 tab - 进到任一 Symfony 项目目录,执行
php public/index.php,看是否抛出 ParseError 或 ClassNotFound —— 表明 autoloader 或扩展缺失(如intl、mbstring) - 访问时报
File not found.(不是 404 页面,而是 Caddy 原生提示):说明root路径错,或public/下没有index.php(比如你误把整个项目当 root,而非 public 子目录)
复杂点在于 FrankenPHP 的日志默认不输出 PHP 错误详情,得手动在 Caddyfile 加 log { output file /var/log/frankenphp/error.log } 并配合 php -m 确认扩展已载入。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











