frankenphp是基于go和caddy的嵌入式php应用服务器,将php运行时直接集成进单二进制,无需nginx或php-fpm;而php-fpm是独立fastcgi进程管理器,依赖外部web服务器,每次请求需重新初始化框架,性能与部署复杂度均更高。

FrankenPHP 是什么,它和 PHP-FPM 有什么根本区别
FrankenPHP 不是 PHP 的替代品,而是用 Go 重写的、嵌入式 PHP 运行时——它把 libphp(PHP 的核心 C 库)直接集成进 Go 二进制中,不依赖外部 php-fpm 进程或 apache2 模块。这意味着:启动快、内存共享、可原生支持 HTTP/2 和 TLS 1.3,且能通过 Go 生态做路由、中间件甚至热重载。
关键差异点:
-
php-fpm是独立守护进程,FrankenPHP 是单进程二进制,frankenphp serve启动即带完整 HTTP 服务 - 没有
fastcgi_pass配置项,也不需要 Nginx 反向代理(除非你主动加) - 不兼容所有 Apache mod_php 特性(比如
.htaccess解析),但支持标准php.ini和扩展加载 - 默认监听
127.0.0.1:8080,不是 9000 端口,别按 FPM 习惯去连
用官方二进制跑通 index.php 的三步操作
2026 年 FrankenPHP 已发布 v1.2.x,macOS/Linux/Windows(WSL2)均提供预编译二进制,无需编译 PHP 源码。
实操步骤(以 Linux/macOS 为例):
- 下载最新版:
curl -L https://github.com/dunglas/frankenphp/releases/download/v1.2.1/frankenphp_1.2.1_linux_x86_64.tar.gz | tar xz - 新建项目目录,放入
index.php:<?php echo "FrankenPHP is running at " . date('Y-m-d H:i:s');
- 执行:
./frankenphp serve --workers=2 --document-root=.,访问http://127.0.0.1:8080即可看到输出
注意:--document-root 必须显式指定,不能省略;若路径含空格或中文,需用引号包裹;Windows 用户请用 frankenphp.exe 替代。
遇到 PHP Warning: Module 'openssl' already loaded 怎么办
这是 FrankenPHP 最常见的启动报错,根源在于它会自动加载系统 PHP 安装目录下的 php.ini(如 /etc/php/8.3/cli/php.ini),而该文件里已启用了 extension=openssl 等扩展——但 FrankenPHP 自带的 libphp 已静态链接这些基础扩展,重复加载就冲突。
解决方法只有两个有效路径:
- 用
--php-ini指向一个精简版php.ini(只保留date.timezone、error_reporting等纯配置项,注释掉所有extension=行) - 更推荐:用
--no-php-ini完全跳过系统 php.ini,靠环境变量控制行为,例如:PHP_INI_SCAN_DIR="" ./frankenphp serve --no-php-ini --document-root=.
别试图改 php.ini 中的 extension_dir 路径——FrankenPHP 不读取该值,它只认自己内置的扩展表。
想用 Laravel 或 Symfony?先绕开 public/index.php 的 PATH_INFO 陷阱
FrankenPHP 默认使用 CGI SAPI 模式,但 Laravel/Symfony 的 public/index.php 依赖 $_SERVER['PATH_INFO'] 做路由解析。而 FrankenPHP 在 CLI 模式下不会自动填充该变量,导致所有路由 404。
必须启用「CGI 模式」并显式传递环境:
- 确保入口文件是标准的
public/index.php(不要重命名) - 启动命令加
--cgi参数:./frankenphp serve --cgi --document-root=public --env=APP_ENV=local - 如果仍 404,检查是否漏了
--document-root=public(不是项目根目录)
另外,$_SERVER['REQUEST_URI'] 是可靠的,Laravel 的 Illuminate\Http\Request 内部会 fallback 到它,所以多数情况加 --cgi 就够用;但自定义路由逻辑强依赖 PATH_INFO 的老项目,得手动在 public/index.php 开头补一行:
$_SERVER['PATH_INFO'] = $_SERVER['REQUEST_URI'];
FrankenPHP 的复杂点不在安装,而在“它看起来像 PHP-FPM,实际却按 Go HTTP Server 的逻辑走”。很多问题本质是 CGI 环境变量缺失、SAPI 模式误判,或对 --document-root 作用域理解偏差。盯住日志里第一个 Warning,它几乎总是真正的起点。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











