frankenphp -m 是唯一可信的查看方式,它启动最小化实例输出php sapi层真实加载的扩展列表(含内置和动态加载),与php -m(cli环境)结果完全不同。

frankenphp -m 是唯一可信的查看方式
直接运行 frankenphp -m——它会启动一个最小化 FrankenPHP 实例,输出其 PHP SAPI 层真实加载的扩展列表(含内置和动态加载的)。这个结果和你系统里 php -m 输出的完全不同,后者查的是 CLI 环境,对 FrankenPHP 服务无参考价值。
常见错误现象:
-
command not found:说明frankenphp未加入$PATH,先用which frankenphp确认路径,再执行/path/to/frankenphp -m - 输出里缺
opcache或pdo_mysql:不是配置漏了,而是这些扩展根本没被内置或加载;-m不显示zend_extension(如 opcache),需结合phpinfo()或opcache_get_status()单独验证
为什么不能用 php -m 或 get_loaded_extensions()
FrankenPHP 的 PHP 运行时是嵌入在二进制内部的,不复用系统 PHP 的配置、php.ini 或扩展目录。即使你本地装了 PHP 8.3 并启用了 redis,php -m 的结果也完全无法反映 FrankenPHP 实际可用的扩展。
更关键的是:get_loaded_extensions() 必须在 FrankenPHP 的运行时上下文中调用才有效——比如写个 info.php 放在 Web 根目录,内容为 <?php print_r(get_loaded_extensions()); ?>,然后通过 HTTP 请求访问。在 CLI 下执行该脚本,得到的仍是系统 PHP 的结果。
扩展没出现在 -m 列表里的常见原因
扩展“写了但没生效”,往往卡在几个确定性环节上:
- FrankenPHP 静态二进制默认基于 NTS(非线程安全)构建,若你塞进去的是 ZTS 扩展(如某些老版本
pdo_sqlite),它会静默失败——frankenphp -m不报错,也不显示,get_loaded_extensions()里也查不到 - 扩展文件路径不对:
extension_dir指向的目录不存在,或.so文件权限不足(必须可读可执行) - 扩展名拼写错误:比如写成
extension=gd.so,但实际文件名是gd.so(对)还是gd2.so(错),得用ls $extension_dir | grep gd确认 - FrankenPHP 独立二进制不支持运行时加载第三方扩展——所有扩展必须在构建阶段编译进二进制,
extension=xxx.so这类 ini 指令在独立模式下完全无效
需要确认扩展是否真能用,得进请求上下文
列出扩展只是第一步,真正决定“能不能用”的是它在 HTTP 请求中能否被调用。比如 curl 在 -m 里有,不代表 curl_exec() 就一定成功——可能因 OpenSSL 版本不兼容导致 TLS 握手失败。
实操建议:
- 写个最小测试脚本
test-curl.php:<?php echo curl_exec(curl_init('https://httpbin.org/get')) ?: 'fail'; ?> - 用
frankenphp run test-curl.php执行,而非php test-curl.php - 观察是否返回 JSON,还是报
SSL certificate problem或空响应——这比看-m输出更能暴露底层兼容性问题
最容易被忽略的是:ZTS 扩展在 FrankenPHP 中不会立即崩溃,而是在首次调用其函数时触发 segmentation fault 或进程卡死,这种问题在线上偶发,日志里只留一条空白退出记录,排查成本极高。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











