必须将public目录设为web根路径,否则asset()生成的url错误导致静态资源404;frankenphp需显式指定--document-root=public,否则src/config/.env等敏感目录将被暴露。

public 目录必须是 Web 根路径,否则 asset() 生成的 URL 全错
FrankenPHP 默认把当前工作目录当作 Web 根,但 Symfony 要求 Web 服务器只暴露 public/ 下的内容。如果直接在项目根目录运行 frankenphp php-server,asset("build/app.css") 会拼出 /build/app.css,而实际文件在 public/build/app.css —— 请求必然 404。
解决方法只有一个:启动时显式指定 public/ 为文档根:
- 命令行启动:
frankenphp php-server --document-root=public - Docker 启动:挂载点必须映射到
/app/public,且容器内工作目录设为/app,再通过--document-root=public指定 - 不加
--document-root=public就等于把src/、config/、.env全部暴露在 HTTP 下,有严重安全风险
静态资源不能放在 src/ 或 templates/,assets:install 不起作用
Symfony 的 php bin/console assets:install 只是把 assets/ 目录下的文件软链或复制到 public/assets/。但 FrankenPHP 不识别这个命令的输出逻辑——它只认 public/ 下真实存在的文件路径。
常见错误现象:asset("assets/app.js") 返回 /assets/app.js,Nginx 能访问,FrankenPHP 返回 404。
- 根本原因:你把
assets/app.js放在了项目根目录或src/下,没真正放进public/assets/ - 正确做法:前端构建(如 Webpack)输出目录必须设为
public/build/,而不是assets/ - 如果必须用
assets:install,得配合--symlink参数,并确认 FrankenPHP 运行用户有读取符号链接的权限(Docker 中尤其容易因 UID 不一致失败)
HTTPS 重定向和 X-Forwarded-* 头在 FrankenPHP 下默认不生效
Symfony 的 Request::isSecure() 和 Twig 的 absolute_url() 依赖 X-Forwarded-Proto 等头判断协议。FrankenPHP 作为反向代理前端时,不会自动添加这些头——它不是 Nginx,不默认信任上游。
这会导致:开发环境正常,部署到 FrankenPHP 后所有 url() 生成 http 链接,即使实际跑在 HTTPS 上。
- 临时修复:在
public/index.php开头手动设置$_SERVER['HTTPS'] = 'on'(仅限单机测试) - 生产方案:用 FrankenPHP 的
Caddyfile显式透传头,例如:header_up X-Forwarded-Proto {http.request.header.X-Forwarded-Proto} || "https" - 更稳妥的做法:在 Symfony 配置中启用信任代理,设置
framework.trusted_proxies并明确列出 FrankenPHP 的监听地址(如127.0.0.1)
var/cache 和 var/log 路径冲突常被忽略
FrankenPHP 启动时默认以当前目录为工作目录,var/cache 和 var/log 会写入该路径下。但如果用 --document-root=public,它仍会从项目根读取 config/、写入 var/ —— 这本身没问题。
真正容易出问题的是 Docker 场景:
- 挂载
./var:/app/var时,若宿主机var/是空目录,容器内首次启动会因权限问题无法创建var/cache/prod - FrankenPHP 的 Go 进程和 PHP 子进程 UID 可能不一致,导致缓存文件属主混乱,后续
cache:clear失败 - 解决方案:启动前运行
mkdir -p var/cache var/log && chmod -R 777 var/(开发),生产环境应固定 UID 并用chown初始化
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











