composer 不编译 c 扩展,仅检查其存在性;c 扩展需手动通过 phpize、make 等工具编译并启用,再在 composer.json 中声明 ext-xxx 依赖,composer update 对其完全无效。

composer update 不会、也不能强制重新编译 C 扩展。C 扩展的编译与 Composer 完全无关,必须手动触发。
为什么 composer update 对 C 扩展完全无效
Composer 只管理 PHP 类库(纯代码包),不接触 PHP 解释器底层。像 ext-redis、ext-swoole、ext-mongodb 这类 C 扩展,是独立于 Composer 的系统级组件:
- Composer 仅在
require中声明"ext-redis": "*"时做存在性检查,报错如PHP extension "redis" is missing -
composer update不调用phpize、不执行make、不修改php.ini - 即使你升级了依赖
phpredis/phpredis(PHP 封装层),底层redis.so仍需单独重编译才能适配新 PHP 版本或修复 ABI 不兼容
真正需要重编译 C 扩展的典型场景
以下情况才需手动重编译,和 composer update 无因果关系:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- PHP 升级后(如从 8.1 → 8.2),已安装的
.so文件因 ABI 变更无法加载,php -m报undefined symbol或直接跳过该扩展 - 扩展源码更新了(如从 GitHub 主干拉了新 commit),但你之前是手动
make install的,没走 PECL 流程 - 启用了新编译选项(如加
--enable-igbinary),需 clean 后重 configure - 更换了 PHP 安装路径(如从
/usr/bin/php切到/opt/php82/bin/php),phpize路径已失效
手动重编译 C 扩展的标准流程(以 redis 为例)
确认当前 PHP 环境路径和扩展目录:
php-config --version php-config --extension-dir php -i | grep extension_dir
然后执行(顺序不可颠倒):
- 进入扩展源码目录(如
cd /path/to/phpredis) - 清理旧构建:
make clean(如有) - 匹配当前 PHP:
phpize --clean && phpize(确保用对版本的 phpize) - 配置并指定目标:
./configure --with-php-config=/path/to/your/php-config - 编译安装:
make && sudo make install - 启用扩展:
echo "extension=redis.so" >> $(php --ini | grep "Loaded Configuration File" | cut -d' ' -f4) - 验证:
php -m | grep redis,成功后重启 PHP-FPM 或 Web 服务
容易被忽略的关键点
很多人以为删了 vendor/ 或跑一遍 composer update 就“刷新了扩展”,其实只是更新了 PHP 封装层(比如 phpredis/phpredis 的客户端类),而 redis.so 仍躺在 extension_dir 里,可能早已 ABI 失效。真正影响运行时行为的是 .so 文件本身是否与当前 PHP 二进制兼容——这个只能靠手动编译控制,Composer 不参与也不感知。










