必须执行frankenphp -m查看其php sapi层真实加载的扩展列表,而非系统php -m;该命令启动最小化实例输出实际启用模块,需结合phpinfo()、opcache_get_status()及http请求中函数调用验证可用性。

用 frankenphp -m 查当前运行时真实加载的扩展
FrankenPHP 启动后加载的扩展,和你系统里 php -m 输出的很可能不一样——它不继承 CLI 配置,也不读你平时调试用的 php.ini。必须查它自己进程实际启用的模块。
最直接的方式是执行:frankenphp -m。这个命令会启动一个最小化 FrankenPHP 实例,输出其 PHP SAPI 层真正加载的扩展列表(含内置和动态加载的)。如果看到 pdo_mysql、curl、mbstring 都在列,说明基础已就位。
- 若报错
command not found,先确认frankenphp二进制路径是否在$PATH,或改用绝对路径调用 - 输出里没有
opcache?别急着装包——它属于zend_extension,-m默认不显示,得靠phpinfo()或opcache_get_status()验证 - 出现
swoole但项目没用它?不用删,FrankenPHP 不会因扩展存在而自动启用协程,不影响稳定性
在 Web 请求上下文中验证扩展是否“可用”
有些扩展(比如 xdebug、apcu)被配置为仅在 CLI 下启用,Web 模式下静默失效。frankenphp -m 看不到它们,但更关键的是:你的 PHP 脚本在 HTTP 请求中能不能调用 gd_info() 或 redis_connect()。
新建一个 check-ext.php 放到项目 public 目录下:
<?php if (!extension_loaded('gd')) {
die('GD extension is missing');
}
if (!function_exists('imagecreate')) {
die('imagecreate() not available');
}
echo "GD OK\n";
print_r(gd_info());
?>
用浏览器或 curl http://localhost:8080/check-ext.php 访问,看是否完整输出。这才是真实请求链路下的结果。
- 返回 500 且日志里有
Call to undefined function?说明该函数所在扩展未在 Web SAPI 下启用 - 扩展名对但函数仍不可用?检查
php.ini中是否用了disable_functions把它禁了 - Laravel 项目建议在
routes/web.php里加个临时路由,直接调get_loaded_extensions(),避免静态文件路由干扰
核对 extension_dir 和扩展文件路径是否匹配
FrankenPHP 不会帮你猜路径。即使 php.ini 里写了 extension=redis,如果 extension_dir 指向的是 /usr/lib/php/8.2,而实际 redis.so 在 /usr/lib/php/8.2/franken,就会静默失败——不报错,也不加载。
运行 frankenphp --php-config 查它实际加载的 php.ini 路径,然后打开该文件,确认两件事:
-
extension_dir的值是否指向 FrankenPHP 自带扩展目录(常见于/usr/lib/php/8.2/franken或 Docker 镜像里的/usr/local/lib/php/extensions/no-debug-non-zts-20220829/) -
extension=行是否未被注释,且扩展名拼写完全一致(extension=gd≠extension=php_gd2) - Linux 下检查对应目录是否存在该
.so文件:ls $(php-config --extension-dir)/gd.so
特别注意:FrankenPHP 官方镜像自带的扩展目录和系统默认 PHP 的 ext/ 是分开的,不能混用。
自定义 C 扩展必须用 frankenphp-build 重编译
直接把你在 PHP-FPM 环境下编译好的 swoole.so 或私有扩展丢进 extension_dir,大概率启动失败,报错类似 undefined symbol: zend_object_std_init。这是因为 FrankenPHP 的 PHP 运行时嵌入在 Go 进程中,Zend 引擎初始化时机和符号可见性与传统 FPM 不同。
- 必须使用 FrankenPHP 提供的
frankenphp-build工具(非phpize + make)重新编译源码 - 编译时需指定目标 PHP 版本(如
--php-version=8.2),并与frankenphp --php-version输出严格一致 - 编译产物是
.so文件,但加载时仍要确保extension_dir指向其所在目录,且extension=xxx名称匹配 - Redis 扩展是个典型:官方推荐用
php8.2-franken-redis包,而非通用php-redis
扩展齐全不是“列表对得上”,而是“请求进来时能跑通”。最容易被忽略的是:worker 模式下某些扩展(如 pcntl)会被 FrankenPHP 主动禁用,经典模式才全量支持——上线前务必确认你用的是哪种模式。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











