curl测试需同时满足三点:HTTP状态码为200、响应体含预期内容(如"ok")、响应头含Server: FrankenPHP;缺一不可,仅浏览器能打开页面不等于接入成功。

curl 测试必须带 -v 并检查三处关键响应
只看浏览器能不能打开页面是不够的。FrankenPHP 启动后,curl -v http://localhost:8000/ 的输出里要同时满足三点才算真正接入:状态码是 200(不是 500 或 404),响应体含预期内容(比如 "ok"),且响应头中出现 Server: FrankenPHP。如果看到 Server: nginx 或没这个 header,说明请求根本没走到 FrankenPHP,而是被本地其他服务劫持了。
文档根路径错位会导致 404 却不报错
用 frankenphp php-server 启动时,默认以当前目录为文档根;但 Laravel、Symfony 等框架入口在 public/ 目录。若没加 --document-root public,访问 / 会 404,而 /index.php 可能也 404(因为 index.php 不在当前目录)。常见表现:
-
curl http://localhost:8000/返回 404,但curl http://localhost:8000/public/index.php能返回内容 → 根路径没对齐 -
curl http://localhost:8000/css/app.css404 → 静态资源路径失效,大概率也是--document-root漏设 - 用
frankenphp run时,Caddyfile 里root * public和handle /api/* { php_server }必须匹配实际目录结构,否则路由全乱
worker 模式下得验证单例是否真复用
开启 --worker 后,PHP 进程常驻,但框架未必真正复用容器。Laravel 中连续调用两个接口,如果 spl_object_id(app('log')) 返回不同值,或 app()->isBooted() 在第二次请求时仍为 false,说明生命周期没接管成功。此时容易出现连接池未复用、静态变量未保留、日志写错文件等问题。验证方式:
- 写一个接口返回
['booted' => app()->isBooted(), 'log_id' => spl_object_id(app('log'))] - 用
curl连续请求两次,对比结果 - 确认入口文件(如
public/index.php)已按官方要求包裹frankenphp_handle_request(),而非直接require_once 'bootstrap/app.php'
HTTPS 和 HTTP/2 不是“配了就通”,得看证书和协议协商
FrankenPHP 本身不终止 TLS,curl -k https://localhost:8000 失败是正常的——它默认不监听 HTTPS 端口。只有 frankenphp run 加上 Caddyfile 且域名可解析时,才可能启用 HTTPS。验证要点:
立即学习“PHP免费学习笔记(深入)”;
- 用
curl -I --http2 -k https://localhost,首行必须是HTTP/2 200,不是HTTP/1.1 - 浏览器开发者工具 Network 标签中任意请求的 Protocol 列显示
h2,才算 HTTP/2 生效 - 若看到证书警告,不要跳过;先确认 Caddy 是否成功生成证书(日志有
autosaved config或https://localhost:443监听提示)
最常被忽略的是:你以为服务起来了,其实只是本地 Apache/Nginx 在响应;你以为走的是 HTTPS,其实请求压根没进 FrankenPHP。每次上线前,拿 curl -v 对着三个点打一遍——端口、路径、header——比等用户反馈快十倍。



















