必须修改php.ini恢复proc_open和proc_get_status函数,因二者被禁用会导致Composer在post-install-cmd等场景报错;若无权限,则需本地安装后上传vendor并仅运行dump-autoload。

必须改 php.ini,其他都是临时绕路——proc_open 被禁用不是 Composer 自身能绕开的问题,而是 PHP 运行时直接拒绝创建子进程。所有“加参数”“换命令”的做法,都只是跳过需要它的环节,一旦遇到 post-install-cmd、Git 拉取、自动 autoload 生成等场景,照样报错退出。
确认被禁用的函数到底有哪些
别猜,直接查。在服务器终端执行:
php -i | grep disable_functions
你会看到类似这样的输出:
disable_functions => exec,shell_exec,passthru,proc_open,proc_get_status => exec,shell_exec,passthru,proc_open,proc_get_status
注意:CLI 和 Web(如 Nginx + PHP-FPM)可能加载不同 php.ini,务必用 php --ini 确认当前命令行用的是哪个配置文件。常见坑是改了 Apache 的 php.ini,但 composer install 是在 CLI 下运行,结果没生效。
修改 php.ini 恢复关键函数(推荐方案)
找到对应 php.ini 文件后,定位 disable_functions 行,删掉 proc_open 和 proc_get_status(二者必须同时启用,缺一不可):
- 修改前:
disable_functions = exec,passthru,shell_exec,proc_open,proc_get_status - 修改后:
disable_functions = exec,passthru,shell_exec
保存后重启服务:
sudo systemctl restart php-fpm
或(Apache 环境):
sudo systemctl restart apache2
验证是否生效:
php -r "var_dump(function_exists('proc_open') && function_exists('proc_get_status'));"
输出 bool(true) 才算真正修复成功。
没权限改 php.ini?那就彻底避开 proc_open 调用
共享主机、部分云平台(如旧版阿里云虚拟主机)通常不允许修改全局配置。此时不能硬扛,要调整工作流:
- 本地完整执行
composer install --prefer-dist --no-scripts --no-plugins,生成完整的vendor/目录 - 把
vendor/和composer.lock一起上传到服务器(注意权限,避免 0777) - 部署后仅需运行
composer dump-autoload --optimize,它不调用proc_open - 在
composer.json中显式配置:"config": { "preferred-install": "dist" },确保未来新增包也走 ZIP 分发,不触发 Git 克隆
这个方案看似麻烦,但比反复试错参数更稳定——只要不在线上运行 update 或带脚本的 install,就永远不会撞上 proc_open。
最容易被忽略的一点:有些环境禁用了 proc_open 却没禁 exec,你以为能用,结果 Composer 内部仍因缺少 proc_get_status 在某些钩子里崩溃。所以验证必须两项一起测,不能只看 proc_open 存在就认为万事大吉。










