Composer报“PHP extension xxx is missing”是因为它仅检查PHP CLI环境是否已加载指定扩展,不负责安装或编译扩展;需确认php -m输出含该扩展、php --ini指向正确配置文件,并确保extension=xxx.so(Linux/macOS)或extension=php_xxx.dll(Windows)在对应php.ini中启用且路径正确。

为什么composer install会报“PHP extension xxx is missing”
这不是 Composer 没装对,而是它压根不负责编译 C 扩展——只做检查。只要 composer.json 里写了 "ext-redis": "*" 或类似项,Composer 就会在安装前查系统是否已加载该扩展;没加载就直接中断,不给你往下走的机会。
常见错误现象:本地 php -m 看不到扩展名,但 composer install 却卡在依赖解析后、下载前的阶段,报错信息明确指向 ext-somecextension 缺失。
- 别急着删
composer.lock或加--ignore-platform-reqs—— 这只是跳过校验,运行时照样 fatal - 确认缺失的是哪个扩展:看报错里的扩展名(如
ext-igbinary),不是包名(igbinary/igbinary) - PHP 版本必须匹配:用
php -v查当前 CLI 版本,再确认你要编译的扩展是否支持该版本(比如 PHP 8.2+ 的ext-grpc需要 >=1.60.0)
从源码编译C扩展的最小可行流程
PECL 或 GitHub 是主要来源,但不能直接 pecl install 就完事——很多新版扩展已弃用 PECL 安装方式,必须手动编译。
以 ext-protobuf 为例(PHP 8.2,Ubuntu 22.04):
git clone https://github.com/protocolbuffers/protobuf.git cd protobuf/php phpize ./configure --with-php-config=/usr/bin/php-config make sudo make install
关键点:
-
phpize必须对应当前 PHP CLI 的版本(which phpize要和php -v一致) -
./configure一定要带--with-php-config参数,否则可能链接到旧版 PHP 的头文件 -
make install输出的.so路径会打印在最后,例如:/usr/lib/php/20220829/protobuf.so
启用扩展前必须核对的三个路径
光把 .so 文件丢进目录不够,PHP 得知道去哪儿找它、加载它、且不冲突。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
执行以下命令获取真实路径:
-
php -i | grep extension_dir→ 得到扩展存放目录(如/usr/lib/php/20220829) -
php --ini→ 找到正在生效的php.ini路径(注意 CLI 和 FPM 可能不同) -
php -r "echo ini_get('extension_dir');"→ 验证是否与上一条一致
然后编辑对应 php.ini,追加一行:
extension=protobuf.so
⚠️ 注意:extension= 后面只写文件名,不带路径;也不能加引号;多个扩展按顺序加载,有依赖关系的(如 igbinary 要早于 redis)得手动调序。
开发机和CI环境如何避免重复编译
每次部署都重编 C 扩展既慢又容易出错。真正可落地的静态编译策略是:预编译 + 版本固化 + 路径隔离。
推荐做法:
- 在 CI 流水线中,用 Docker 构建镜像时一次性编译好所有 C 扩展,并打包进
php:8.2-cli基础镜像 - 开发机统一用
phpbrew或asdf管理多 PHP 版本,每个版本下独立编译扩展,避免交叉污染 - 不要共享
/usr/lib/php/*下的.so文件——不同 minor 版本(如 8.2.12 vs 8.2.15)的 ABI 可能不兼容 - 验证环节加一行:
php -d extension=protobuf.so -m | grep protobuf,确保扩展能被独立加载,不依赖php.ini
最常被忽略的一点:PHP-FPM 和 CLI 使用的 php.ini 往往不是同一个文件,改完记得分别重启 php-fpm 和测试 CLI 命令。

















