composer会覆盖vendor中本地修改,因它将vendor视为纯输出目录,任何手动修改均不被保留;正确做法是将修改移至app/src下,通过autoload.files、继承重写、fork仓库或框架扩展点实现可维护变更。

composer install 为什么会覆盖 vendor 里的本地修改
它不会“覆盖本地代码”,但会彻底重置 vendor/ 目录到 composer.lock 所声明的状态。如果你手动改过 vendor/topthink/framework/src/ 下的某个文件,composer install 或 composer update 一执行,那个文件就没了——因为 Composer 把 vendor/ 当作纯输出目录,任何手改都被视为临时、不可靠、不被保护的操作。
哪些操作实际等于“在 vendor 里写代码”
以下行为都会导致下次 composer install 失效,且极难追溯:
- 直接编辑
vendor/下任意 PHP 文件(比如打日志、临时注释掉某行) - 把自定义类拷进
vendor/某个包的src/里,指望它被自动加载 - 用
sed -i或 IDE 全局替换修改vendor/中的硬编码路径
这些不是“调试技巧”,是部署事故的前奏。Composer 不提供 diff 或 patch 机制来保留这类变更。
真要改依赖逻辑,该走哪条路
必须把修改从 vendor/ 移出去,变成项目可维护、可版本控制的部分:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 用
autoload.files在composer.json里引入自己的补丁文件,覆盖原逻辑(适合小修) - 继承原类并重写方法,在自己的命名空间下使用,再通过 DI 替换原始服务(ThinkPHP 可用
bind或容器extend) - 发 PR 给上游包;若被拒或周期长,可 fork 后用
repositories指向你的分支,并锁死"yourname/framework": "dev-fix-xxx as 6.1.5" - 对框架核心如
topthink/framework,优先用conflict锁版本,再通过事件、中间件、命令行指令等扩展点介入,而非动源码
所有这些方式,都确保修改落在 app/ 或 src/ 下,受 Git 管理,且不会被 composer install 清洗。
万一已经改了 vendor,怎么安全回滚
别靠记忆或截图,用 Git 快速识别和丢弃:
- 运行
git status --no-ignore-vcs(加--no-ignore-vcs是为了绕过 .gitignore 对 vendor 的忽略) - 如果看到
vendor/下一堆 modified 文件,立刻git checkout -- vendor/回退全部 - 若已
git add进暂存区,先git restore --staged vendor/,再git checkout -- vendor/ - 之后立即执行
composer install --no-scripts,避免 post-install-cmd 脚本二次污染
Git 把 vendor/ 当作二进制垃圾目录是有道理的——它本就不该承载任何你希望保留的逻辑变更。










