frankenphp php-server 不是万能启动命令,它仅在显式指定 -root、-addr、-index 等参数且路径/文件存在可读时才有效;否则常因找不到 index.php 或 DOCUMENT_ROOT 错误导致空白页或404。

直接说结论:frankenphp php-server 不是万能启动命令,它只在特定目录结构和配置下才有效;多数人执行后看到空白页或 404,根本原因不是 FrankenPHP 没跑起来,而是它没找到 PHP 入口文件或没启用正确的路由规则。
为什么 frankenphp php-server 经常不工作
这个命令本质是启动一个「默认配置的 FrankenPHP 实例」,但它不做任何自动探测:不扫描 index.php、不读取项目根目录下的 Caddyfile、也不假设你用的是 Laravel 或 WordPress。它只做两件事:监听 :8080,并把所有请求转发给 index.php(如果存在且可执行)。
常见失效场景包括:
- 当前目录下没有
index.php,只有public/index.php(如 Laravel) - 有
index.php,但里面用了$_SERVER['DOCUMENT_ROOT']或硬编码路径,而 FrankenPHP 的DOCUMENT_ROOT默认指向当前工作目录 - 想托管静态资源(CSS/JS),但没配
php_server的try_files规则,导致/style.css直接 404 - 运行在非标准端口(比如被占用了),但没加
-addr参数指定新端口
php-server 必须配合的最小配置项
要让 frankenphp php-server 真正可用,至少得告诉它三件事:根目录在哪、PHP 入口在哪、静态文件怎么处理。这些不能靠猜,得显式声明。
立即学习“PHP免费学习笔记(深入)”;
- 用
-root明确指定 Web 根目录,例如frankenphp php-server -root public/(Laravel/Symfony 必须这么写) - 用
-addr指定监听地址,避免端口冲突,例如-addr :8000 - 如果入口不是
index.php(比如叫app.php),必须加-index,例如-index app.php - 若需支持
.js、.css等静态文件,-root路径下必须包含它们,且 FrankenPHP 会自动服务——但前提是这些文件真在那个目录里
典型可用命令示例:
frankenphp php-server -root public/ -addr :8000 -index index.php
注意:这个命令不会读取你项目里的 Caddyfile,它走的是内置精简模式,所有逻辑都由参数控制。
什么时候该放弃 php-server,改用 frankenphp run
一旦你遇到以下任一情况,就别硬扛 php-server 了,立刻切到 frankenphp run + Caddyfile:
- 需要 HTTPS(
php-server不支持 TLS) - 要配置重写规则(比如 Laravel 的
try_files或 WordPress 的 permalink) - 要同时托管多个子域名或路径前缀
- 要用环境变量注入配置(如
APP_ENV=prod) - 想启用 worker 模式(
php-server只支持 classic 模式)
frankenphp run 会加载当前目录下的 Caddyfile,所有 Caddy 原生能力(HTTP/3、自动证书、Mercure 推送)全都能用。哪怕只是加一行 encode gzip 或 log,也比折腾 php-server 的参数强。
容易被忽略的权限与路径细节
FrankenPHP 启动时对路径敏感,且不报错提示,只静默失败:
-
-root路径必须存在且可读,否则返回空白页(不是 404) -
-index指定的文件必须在-root下可访问,且 PHP 有执行权限(比如不能是符号链接指向不可达路径) - Windows 用户要注意反斜杠路径,
frankenphp php-server -root "C:\myapp\public"会失败,必须用正斜杠:C:/myapp/public - Linux/macOS 上如果用
sudo frankenphp php-server,当前工作目录可能变成/root,而不是你预期的项目路径
最稳妥的做法:cd 进项目 public/ 目录,再执行 frankenphp php-server -root . -addr :8000——路径绝对明确,无歧义。



















