补丁没生效需先确认cweagans/composer-patches是否已安装,它非composer原生功能,未安装则extra.patches配置无效;必须通过composer require --dev cweagans/composer-patches:^1.7显式安装,并确保配置位于项目根目录composer.json的extra.patches中,路径相对该文件,补丁格式为lf换行、无前缀的git diff,且需删除vendor和composer.lock后重装才能触发应用。

补丁没生效?先确认 cweagans/composer-patches 装了没
cweagans/composer-patches 不是 Composer 内置功能,它不装,extra.patches 就是废配置。
很多“补丁不执行”的问题,根源就在这一步漏了。
- 运行
composer require --dev cweagans/composer-patches:^1.7(推荐 v1.7+,兼容 Composer 2.x 和 PHP 8.2+) - 安装后检查
composer.json的require-dev是否新增了"cweagans/composer-patches": "^1.7" - 别用全局安装:
composer global require对当前项目完全无效 - 如果之前已跑过
composer install,删掉vendor/和composer.lock再重来——缓存包会跳过 patch 阶段
extra.patches 配置写在哪?只认根项目 composer.json
插件只读取你项目根目录下的 composer.json,其他位置全无效:
- 子模块、私有包自己的
composer.json里写extra.patches→ 插件看不见 -
repositories里定义的包,其composer.json中的 patches → 不触发 - 键名必须是标准格式:
"monolog/monolog",不能是"./vendor/monolog/monolog"或"Monolog\Monolog" - 值必须是对象或数组:单个补丁可用字符串(
"Fix null check": "patches/xxx.patch"),多个必须用数组 - 路径是相对于
composer.json的:写"patches/xxx.patch"就真得把文件放项目根下的patches/目录里
patch 文件为什么总报错 “can't find file to patch”?路径和换行是两大雷区
插件底层调用系统 patch 命令,它对格式极其敏感。90% 的失败源于这两点:
- 补丁头路径必须匹配 vendor 解压结构:比如修
monolog/monolog,补丁里得是src/Logger.php,不是a/src/Logger.php或vendor/monolog/monolog/src/Logger.php - 换行符必须是 LF(Unix):Windows 默认 CRLF,会导致解析失败;用
file patches/*.patch检查,输出含with CRLF line terminators就得转 - 最稳生成方式:进到
vendor/monolog/monolog目录,改完后运行git diff --no-prefix > ../../patches/monolog-fix.patch - 提前校验:在项目根运行
git apply --check patches/monolog-fix.patch,无输出才表示可安全应用 - 空格、中文路径别碰:JSON 解析会失败;命名用短横线,如
laravel-session-race.patch
补丁应用失败后怎么调试?看日志、查版本、试回滚
composer install -v 是唯一可靠入口,关键线索藏在 verbose 输出里:
- 成功时会打印:
Applying patch 'Fix null coalesce' to vendor/monolog/monolog - 失败时典型报错:
error: patch failed: src/Logger.php:42,说明第 42 行 hunk offset 偏移不匹配 - 常见原因:你打补丁用的源码版本和
composer.lock锁定的版本不一致 - 应对方式:
- 进
vendor/monolog/monolog,用git log -n 1看当前 commit,对比补丁生成时的 base - 在 patch 配置里加
"revert": true,让插件先反向打再正向打,有时能绕过 strict offset - 加
--no-cache强制重拉包:composer install --no-cache -v - 临时关插件排查干扰:
composer install --no-plugins -v
- 进
补丁不是写一次就一劳永逸的事。包版本一动,patch 很可能失效;而真正容易被忽略的,是补丁文件本身是否仍基于当前锁定版本生成——每次 composer update 后,都该重新验证 git apply --check。











