FrankenPHP命令不识别主因是PATH未配置或二进制无执行权限;Linux/macOS需chmod +x并移至/usr/local/bin,Windows需手动添加环境变量;验证应运行frankenphp php-cli -v而非which。

frankenphp 命令不识别?先确认 PATH 和二进制权限
运行 frankenphp --version 报 “command not found”,大概率是 PATH 没配对,或 Linux/macOS 下缺少执行权限。Windows 用户解压后必须手动把目录加进系统环境变量;Linux/macOS 用户下载二进制后别忘了 chmod +x frankenphp,再用 sudo mv frankenphp /usr/local/bin/ 移动——别直接软链接到未加权目录,否则后续 frankenphp php-server 可能因权限失败。
验证是否真装好:不是只看 which frankenphp,而是执行 frankenphp php-cli -v。这个命令调用的是 FrankenPHP 内置的 PHP 解释器,能同时确认二进制可用 + 内置 PHP 版本正确(Laravel 项目通常要求 8.2+,frankenphp php-cli -m 可查扩展是否齐备)。
Caddyfile 配置错位?经典模式下它其实可以不要
很多人卡在写 Caddyfile 上,但其实“经典模式”(即零改动替代 Nginx+PHP-FPM)根本不需要配置文件:frankenphp php-server 默认就监听 localhost:8000,自动把当前目录当文档根,index.php 和静态文件都能直接访问。只有当你需要 HTTPS、自定义域名、反向代理或多站点时,才需要 Caddyfile。
如果决定写,注意两个易错点:
立即学习“PHP免费学习笔记(深入)”;
- 全局块
{ frankenphp { ... } }必须放在最前面,不能嵌套在站点块里 -
php_server指令只能出现在站点块(如localhost { ... })内,单独写会报unknown directive 'php_server'
最小可用配置就三行:
{ frankenphp { num_threads auto } }
localhost { php_server }Laravel 迁移后 500 错误?重点检查扩展和 .env 加载
“零改动迁移”成立的前提是:你项目依赖的 PHP 扩展全在 FrankenPHP 内置环境中存在。常见翻车点是 ext-pdo_mysql、ext-redis、ext-intl 缺失——frankenphp php-cli -m | grep pdo 能快速筛查。Docker 用户用 dunglas/frankenphp:latest 镜像时,必须显式 RUN install-php-extensions pdo_mysql redis intl,官方镜像默认不带这些。
另一个隐形坑:FrankenPHP 经典模式下,.env 文件不会被自动加载(不像 Laravel Sail 或 artisan serve)。确保你的 public/index.php 开头有 Dotenv\Dotenv::createImmutable(__DIR__.'/..')->load();,或改用 frankenphp run 命令(它会自动处理环境变量加载)。
HTTP/3 测试失败?curl --http3 不等于服务端已启用
curl -I https://localhost --http3 返回 Unknown option --http3 是 curl 版本太老(需 7.64+),但即使命令成功,也不代表 HTTP/3 真跑起来了。关键看响应头有没有 alt-svc。没出现?问题大概率出在 Caddyfile 全局配置漏了 servers { protocol { experimental_http3 } },或者 UDP 端口 443 被防火墙拦了。
本地测试时,别用 localhost 域名——Let’s Encrypt 不签,Caddy 就不会启用 HTTPS,HTTP/3 更无从谈起。开发阶段用 test.local 并在 hosts 文件映射到 127.0.0.1,Caddy 才会走自签名流程并开启 HTTP/3。
真正麻烦的从来不是启动命令本身,而是扩展缺失时的静默失败、Caddyfile 语法位置错乱导致的服务假启动、以及 HTTP/3 依赖的底层网络条件被忽略——这些地方一错,日志里往往只有一行 connection reset,得靠 curl 头和 frankenphp php-cli 逐层拆解。



















