cgr不是composer global require的替代品,它仅支持临时、隔离、一次性执行,不注册命令到$path,不生成持久二进制,也无法管理已执行包。

cgr 不是 composer global require 的替代品,它压根不提供“全局命令长期可用”能力——每次执行完就清理临时环境,无法注册到 $PATH,也不生成持久二进制。真要管理多个全局工具版本,得先分清场景:是一次性的调试任务,还是需要稳定复用的 CLI 工具。
为什么 cgr install 后命令不能一直用?
cgr 的设计目标就是临时、隔离、一次性:下载包 → 创建独立 vendor → 执行二进制 → 默认不清理(但也不保留)。它不会往 ~/.cgr/bin/ 写脚本,除非你手动加了 --bin-dir 参数或配置了 bin-dir;更关键的是,它不修改 autoload.php 加载路径,也不写入任何全局注册表。
- 执行
cgr laravel/installer -- new myapp后,laravel命令立刻失效 - 没有
cgr list或cgr uninstall,所有“已安装”状态只存在于文件系统里 - 默认临时目录在
~/.cgr/tmp/,不自动清理,下次运行可能复用旧缓存导致版本错乱
想让多个版本的 phpstan 共存并随时调用?别用 cgr
你需要的是可复现、可定位、可卸载的长期可用命令,不是跑完即焚的快照。这时候 cgr 反而增加不确定性:它不锁版本、不生成 composer.lock、不校验 PHP 版本兼容性。
- 正确做法是用
composer create-project固定路径安装:composer create-project phpstan/phpstan:1.10.3 ~/tools/phpstan-1.10.3 - 为每个版本建独立 alias:
alias phpstan-1.10='php ~/tools/phpstan-1.10.3/bin/phpstan' - 不同 PHP 版本需显式绑定:写 wrapper 脚本,第一行指定
/usr/local/bin/php81而非裸php - 升级时删目录 + 重装,不依赖“覆盖安装”,避免 autoload 映射残留
什么时候该坚持用 cgr?只限这三类场景
它真正适合的,是你确定这辈子只跑一次、且不想污染本地环境的操作。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 临时验证某个
dev-main版本是否修复了你的 bug:cgr phpstan/phpstan:dev-main -- --version - 给老项目快速跑一次代码风格修复:
cgr friendsofphp/php-cs-fixer:^3.0 -- fix ./src --rules=@PHP80 - 生成某工具的初始配置(如 PHPStan 的
phpstan.neon),之后就丢掉:cgr phpstan/phpstan -- generate-baseline
注意:必须显式指定版本约束(如 ^3.0),否则默认拉 dev-main,很可能失败;执行完建议手动 rm -rf ~/.cgr/tmp/*,避免下次误用缓存。
PATH 和 autoload 冲突才是真坑,不是 cgr 能绕开的
无论用 global require 还是 cgr,只要把命令放进 $PATH,就逃不开 shell 查找顺序和 autoload 加载优先级问题。比如 which phpunit 返回的是全局路径,但项目里 vendor/autoload.php 根本没加载它。
- CI/CD 中永远写全路径:
./vendor/bin/phpunit,而不是裸命名单词 - 开发时进项目目录再执行,别依赖全局 PATH 顺序
- 检查 autoload 是否被污染:
head -n 3 $(which phpunit)看它 require 的是不是../vendor/autoload.php,且这个../vendor是不是你项目的
所谓“全局工具管理”,本质是承认每个 CLI 工具都应该有自己明确的生命周期、路径归属和 PHP 环境绑定——cgr 只帮你省了一次 rm -rf,但没解决任何根本问题。










