Composer全局工具版本锁不住,因global require仅修改composer.json、不生成lock文件、不校验/覆盖旧二进制;正确做法是手动进入~/.composer/vendor执行require--no-update、rm-rf vendor后install,或用create-project隔离安装并绑定PHP版本。

全局工具版本为什么锁不住
因为 composer global require foo/bar:1.2.3 只改 ~/.composer/composer.json 的 require 字段,不生成 composer.lock,也不校验已装包是否真匹配。下次运行 foo 命令,实际加载的可能是旧版残留的类或更高版冲突依赖。
常见错误现象:phpstan --version 显示 1.10,但 composer global show phpstan/phpstan 返回 1.12 —— 说明 bin 文件没更新,autoload 映射还指向旧路径。
- global install 不触发 lock 文件生成,版本约束仅在安装瞬间生效
- 已存在的
~/.composer/vendor/bin/phpstan不会被覆盖,哪怕新版本已下载 -
composer global update会重装全部全局包,可能意外升级其他工具的依赖(如把 symfony/console 从 v5 升到 v6),间接破坏项目里php artisan的兼容性
强制固化版本的三步手动流程
绕过 global require 的“只写不装”惯性,必须手动触发 lock 生效和二进制重建:
- 进入全局 vendor 目录:
cd $(composer global config home --absolute)/vendor - 执行
composer require --no-update foo/bar:1.2.3(只改 composer.json,不碰现有依赖) - 删掉旧依赖树:
rm -rf composer/ autoload.php .lock,再运行composer install
这一步确保 composer.lock 被写入且所有依赖按锁定版本解析,不是“满足约束的最新版”。Windows 用户对应路径是 %APPDATA%\Composer\vendor,命令用 rd /s /q composer && composer install。
PHP 版本冲突时别碰 global
全局没有 PHP 版本隔离机制。比如你本地 CLI 是 PHP 7.4,但想用 PHPStan 1.10(要求 PHP 8.1+),composer global require phpstan/phpstan:^1.10 会因依赖约束失败,或退而求其次装一个降级兼容版(如 1.9.x),结果静态分析漏报问题。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
正确做法是用 create-project 独立安装并绑定 PHP:
composer create-project phpstan/phpstan:1.10.3 ~/tools/phpstan-1.10.3 echo '#!/bin/bash\n/usr/local/bin/php81 ~/tools/phpstan-1.10.3/bin/phpstan "$@"' > /usr/local/bin/phpstan-1.10 chmod +x /usr/local/bin/phpstan-1.10
这样调用 phpstan-1.10 --version 就能稳定跑在指定 PHP 版本上,不干扰其他工具。
卸载后命令还在?两处残留必清
composer global remove foo/bar 只删 composer.json 条目和 vendor/foo/bar 目录,但不会动以下两处:
- 二进制文件:Linux/macOS 是
~/.composer/vendor/bin/foo,Windows 是%APPDATA%\Composer\vendor\bin\foo.bat - autoload 映射:旧类路径仍存在
~/.composer/vendor/composer/autoload_psr4.php里,PHP 还会加载
所以卸载后 which foo 仍有输出、foo --version 仍能运行。清理必须两步走:rm ~/.composer/vendor/bin/foo + composer global dump-autoload。漏掉第二步,下次 global require 可能复用旧映射,导致类找不到。
真正麻烦的不是装错,而是残留 autoload 映射和 PATH 顺序混在一起——你以为删干净了,其实它还在后台悄悄加载着三年前的旧版本类。

















