资讯动态

FrankenPHP 从源码编译指南:以 libphp 动态库方式构建可执行文件

发布时间:2026/9/15 20:36:25 来源:尧图企业网站定制
FrankenPHP 从源码编译指南以 libphp 动态库方式构建可执行文件【免费下载链接】frankenphp The modern PHP app server项目地址: https://gitcode.com/GitHub_Trending/fr/frankenphp本指南基于官方文档 docs/compile.md西班牙语版见 docs/es/compile.md整理讲解如何在 Linux、FreeBSD 与 macOS 上从源码构建 FrankenPHP 二进制先准备以libphp动态库形式提供的 PHP再通过xcaddy或原生go build把 PHP 嵌入 Caddy 服务器。读完本文你将掌握 PHP 的 ZTS 配置要点、可选功能的构建标签用法、以及如何扩展自定义 Caddy 模块并理解仓库中 cgo 桥接层的底层实现。编译模型以共享库加载 PHPFrankenPHP 并非把 PHP 解释器静态复制进二进制而是将 PHP 编译为共享库Linux/macOS 下的libphp.so/libphp.dylib在 Go 程序启动时通过 cgo 动态加载。这种动态链接方式是官方推荐的做法另一条路是完全静态或基本静态构建。从源码可以看到 cgo 的链接声明集中在 cgo.go// #cgo unix LDFLAGS: -lphp -lm -lutil // #cgo linux LDFLAGS: -ldl -lresolv // #cgo darwin LDFLAGS: -Wl,-rpath,/usr/local/lib -liconv -ldl它分别针对 unix / linux / darwin 指定了-lphpPHP 共享库、-lm数学库等链接参数这正是加载 PHP 作为共享库这一编译模型在源码层面的直接体现。因此编译机器上必须存在与目标平台匹配、且开启了 ZTS线程安全的 PHP 构建。安装 PHP版本与前置条件FrankenPHP 兼容PHP 8.2 及以上版本。核心要求是提供libphp共享库并且是ZTSZend Thread Safety变体——因为 FrankenPHP 会在 Go 的 goroutine 中并发调度 PHP 线程非 ZTS 的 PHP 无法安全并发执行。方式一用 Homebrew 安装Linux 与 macOS最省事的方式是使用 Homebrew PHP 提供的 ZTS 预编译包。若尚未安装 Homebrew请先安装它然后执行brew install shivammathur/php/php-zts brotli watcher brew link --overwrite --force shivammathur/php/php-ztsshivammathur/php/php-ztsZTS 版 PHP提供php-config与libphpbrotli可选用于 Brotli 压缩支持watcher可选用于文件变更检测worker 热重载。brew link --overwrite --force确保php-config、php等命令覆盖系统默认版本从而被后续编译步骤正确引用。方式二从源码编译 PHP如果你需要自定义 PHP 扩展或特定版本可以从 PHP 官方下载页 获取源码并解压tar xf php-* cd php-*/随后运行configure脚本。以下旗标是强制项FrankenPHP 正常运行的前提其余扩展项可按需追加。Linux 与 FreeBSD./configure \ --enable-embed \ --enable-zts \ --disable-zend-signals \ --enable-zend-max-execution-timers各旗标含义旗标作用--enable-embed生成嵌入式 SAPI即libphp共享库FrankenPHP 必需--enable-zts开启 Zend 线程安全多线程并发调度必需--disable-zend-signals关闭 Zend 的信号处理避免与 Go 运行时信号机制冲突--enable-zend-max-execution-timers启用 Zend 最大执行定时器配合max_execution_time等超时控制macOS先用 Homebrew 安装所需与可选依赖brew install libiconv bison brotli re2c pkg-config watcher echo export PATH/opt/homebrew/opt/bison/bin:$PATH ~/.zshrclibiconvPHP 字符集转换依赖bisonPHP 解析器生成所需Homebrew 的 bison 是 keg-only需手动加入PATH否则./configure可能报错re2c词法分析器生成工具pkg-config供./configure探测依赖brotli、watcher可选功能依赖同上。然后运行./configure \ --enable-embed \ --enable-zts \ --disable-zend-signals \ --with-iconv/opt/homebrew/opt/libiconv/注意 macOS 下未强制开启--enable-zend-max-execution-timers且显式指定了--with-iconv指向 Homebrew 的 keg-only 路径。编译并安装 PHPmake -j$(getconf _NPROCESSORS_ONLN) sudo make install$(getconf _NPROCESSORS_ONLN)自动取 CPU 逻辑核心数做并行编译。安装完成后php-config --includes、php-config --ldflags、php-config --libs即可供下一步使用。安装可选系统依赖或使用构建标签禁用FrankenPHP 的若干特性依赖可选的系统库若未安装可以通过Go 构建标签build tags在编译时禁用特性依赖禁用的构建标签Brotli 压缩Brotlinobrotli文件变更时重启 workerWatcher CnowatcherMercure 实时推送Mercure Go 库自动安装AGPL 许可nomercure仓库中这些标签对应着条件编译文件例如禁用 watcher 的 watcher-skip.go//go:build nowatcher package frankenphp var errWatcherNotEnabled errors.New(watcher support is not enabled) func initWatchers(o *opt) error { for _, o : range o.workers { if len(o.watch) ! 0 { return errWatcherNotEnabled } } return nil }也就是说带nowatcher标签编译后若配置里仍为 worker 设置了watch目录运行时会返回 watcher support is not enabled 错误。同类文件还包括 caddy 目录下的 br-skip.go 与 mercure-skip.go。注意 Mercure 依赖虽然会自动安装但其许可证为 AGPL如果项目有许可证合规要求可用nomercure标签剔除。编译 Go 应用PHP 就绪后即可构建最终二进制。推荐方式使用 xcaddyxcaddy 是 Caddy 官方构建工具能轻松追加 Caddy 模块与 FrankenPHP 扩展CGO_ENABLED1 \ XCADDY_GO_BUILD_FLAGS-ldflags-w -s -tagsnobadger,nomysql,nopgx \ CGO_CFLAGS$(php-config --includes) \ CGO_LDFLAGS$(php-config --ldflags) $(php-config --libs) \ xcaddy build \ --output frankenphp \ --with github.com/dunglas/frankenphp/caddy \ --with github.com/dunglas/mercure/caddy \ --with github.com/dunglas/vulcain/caddy \ --with github.com/dunglas/caddy-cbrotli # 在此追加更多 Caddy 模块与 FrankenPHP 扩展 # 若希望基于本地 frankenphp 源码编译可追加 # --with github.com/dunglas/frankenphp$(pwd) \ # --with github.com/dunglas/frankenphp/caddy$(pwd)/caddy参数逐项说明CGO_ENABLED1必须开启 cgo否则无法链接libphpCGO_CFLAGS$(php-config --includes)把 PHP 头文件目录传给 C 编译器CGO_LDFLAGS$(php-config --ldflags) $(php-config --libs)传入 PHP 的链接参数与库-ldflags-w -s去掉 DWARF 调试信息与符号表缩小二进制体积-tagsnobadger,nomysql,nopgx剔除 Caddy 附带的 badger/MySQL/PostgreSQL 存储模块减小体积、缩短编译时间--with github.com/dunglas/frankenphp/caddy引入 FrankenPHP 的 Caddy 模块。这正是仓库主入口的模块组合方式——caddy/frankenphp/main.go 中导入了_ github.com/caddyserver/caddy/v2/modules/standard _ github.com/dunglas/frankenphp/caddy _ github.com/dunglas/mercure/caddy _ github.com/dunglas/vulcain/caddy而 caddy/go.mod 也印证了dunglas/caddy-cbrotli、dunglas/mercure/caddy、dunglas/vulcain/caddy均为官方组合的一部分。仓库根目录的 go.sh 封装了同样的旗标逻辑还额外引入$(sh $(dirname $0)/mtls-cflags.sh)处理 mTLS 相关编译参数并支持通过PHP_CONFIG环境变量指定自定义php-configPHP_CONFIG${PHP_CONFIG:-php-config} GOFLAGS$GOFLAGS -tagsnobadger,nomysql,nopgx \ CGO_CFLAGS$CGO_CFLAGS $(${PHP_CONFIG} --includes) $(sh $(dirname $0)/mtls-cflags.sh) \ CGO_LDFLAGS$CGO_LDFLAGS $(${PHP_CONFIG} --ldflags) $(${PHP_CONFIG} --libs) \ go $[!TIP]若使用musl libcAlpine Linux 默认且运行Symfony可能需要调大默认线程栈大小否则会出现类似PHP Fatal error: Maximum call stack size of 83360 bytes reached during compilation. Try splitting expression的错误。解决办法是把XCADDY_GO_BUILD_FLAGS改为XCADDY_GO_BUILD_FLAGS$-ldflags -w -s -extldflags \-Wl,-z,stack-size0x80000\栈大小数值按应用实际需求调整。备选方式不使用 xcaddy也可以不经过 xcaddy直接拉取源码后用go命令构建curl -L https://github.com/php/frankenphp/archive/refs/heads/main.tar.gz | tar xz cd frankenphp-main/caddy/frankenphp CGO_CFLAGS$(php-config --includes) CGO_LDFLAGS$(php-config --ldflags) $(php-config --libs) go build -tagsnobadger,nomysql,nopgx该方式进入caddy/frankenphp目录即包含 main.go 的入口模块直接编译。此目录还自带了 Caddyfile 与 default.pgo预配置文件用于引导式性能优化便于直接产出生产可用的二进制。验证与后续使用编译产物是一个名为frankenphp的可执行文件本质是内嵌了 PHP 运行时的 Caddy 服务器。你可以直接用仓库内的测试 Caddyfile 验证./frankenphp run --config /data/web/disk1/git_repo/GitHub_Trending/fr/frankenphp/testdata/Caddyfile或查看 package/Caddyfile 与 profiles/app/Caddyfile.regular对应 worker 模式见 profiles/app/Caddyfile.worker了解生产配置形态。日常运行、worker 模式与静态编译的更多细节可继续阅读 docs/worker.md、docs/static.md 与 docs/config.md。小结从源码编译 FrankenPHP 的完整链路可归纳为三步准备 PHP安装或编译 ZTS 版 PHP8.2确保产出libphp共享库处理可选依赖安装 Brotli / watcher或按需使用nobrotli、nowatcher、nomercure构建标签禁用对应特性构建 Go 二进制用xcaddy推荐便于扩展模块或直接go build通过php-config注入头文件与链接参数完成编译。理解 cgo.go 中的链接声明与各*-skip.go条件编译文件能帮助你在遇到平台相关编译问题时快速定位根因而go.sh则提供了一条与文档命令等价的、可复用的构建入口。【免费下载链接】frankenphp The modern PHP app server项目地址: https://gitcode.com/GitHub_Trending/fr/frankenphp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价