frankenphp内置服务器默认仅处理.php文件,css/js等静态资源需配置router.php并正确匹配request_uri路径,否则直接返回404;nginx反代或fpm模式下,须由nginx显式配置root和location规则服务静态文件。

FrankenPHP 启动后 CSS/JS 图片返回 404
FrankenPHP 内置服务器默认只处理 .php 文件,其他后缀(如 .css、.js、.png)直接被拒绝,不读取也不返回——这不是权限或路径问题,是设计如此。不配 router 就没法服务静态资源。
必须提供一个 router.php 文件,并在启动时显式传入:
php -S localhost:8000 router.php
关键点:
-
return false是必须的,不是exit或die;否则静态文件无法由内置服务器原生返回 - 正则要覆盖你实际用的后缀,比如用了
.webp或.svg,就得加进去 - 如果项目入口不在当前目录(比如
public/下启动),__DIR__要调整为__DIR__ . '/public'等相对路径
router.php 配置后仍 404,检查请求路径是否匹配
常见错位:浏览器访问 /assets/app.css,但文件实际在 public/css/app.css,而 router.php 里写的匹配是 $_SERVER["REQUEST_URI"] —— 它包含完整 URL 路径,不是文件系统路径。匹配失败就 fallback 到 index.php,若该文件又不存在或没处理静态逻辑,就 404。
验证方式:在 router.php 开头加一行:
file_put_contents('debug.log', print_r($_SERVER["REQUEST_URI"], true) . "\n", FILE_APPEND);
然后访问一个静态资源,看日志里记录的 URI 是否和你预期一致。特别注意:
- 是否有前导斜杠(
/assets/vsassets/) - 是否带查询参数(
style.css?v=1.2),正则需兼容? - 大小写是否一致(Linux 系统下
App.css≠app.css)
Nginx 反向代理 FrankenPHP 时静态文件 404
如果你把 FrankenPHP 当作后端,前面套了 Nginx,那 404 很可能来自 Nginx 自己的 location 规则,根本没把静态请求转发给 FrankenPHP。
典型错误配置:
location / { proxy_pass http://127.0.0.1:8000; }
这只会代理根路径,/css/app.css 这类请求会由 Nginx 自己找文件,而它默认没配 root,自然 404。
正确做法是显式声明静态资源由 Nginx 直接服务:
- 确保 Nginx 的
root指向你的public/目录(如root /var/www/myapp/public;) - 加一条
location ~* \.(css|js|png|jpg|gif|svg|woff2|ttf)$块,里面用try_files $uri =404; - PHP 请求才走
proxy_pass,例如location ~ \.php$(虽然 FrankenPHP 不需要 .php 后缀,但路由逻辑常依赖此判断)
PHP-FPM 模式下 FrankenPHP 静态文件 404
FrankenPHP 支持 FPM 模式,但此时它不接管静态文件——那是 Web 服务器(Nginx/Apache)的事。如果你启用了 FPM,却没在 Nginx 中配置 location 规则来服务静态资源,所有非 PHP 请求都会因 Nginx 找不到文件而返回 404。
重点检查:
- Nginx 的
root是否指向public/目录(不是项目根目录) - 有没有遗漏
location /块里的try_files $uri $uri/ /index.php?$query_string;—— 缺少这个,连伪静态路由都进不了 FrankenPHP - 如果用了子目录部署(如
https://example.com/myapp/),root和alias容易配混,alias末尾不能加斜杠,root末尾也不该加
最易忽略的是:FrankenPHP 的 FPM 模式下,它只响应 index.php 或你显式配置的入口脚本,其余一切静态文件必须由 Nginx 兜底,没得商量。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











