本地包调试必须物理隔离,唯一安全方式是用COMPOSER环境变量加载独立composer.local.json文件,其repositories仅含path类型本地源,且路径须相对该文件位置;Windows需管理员权限、Docker需SYS_ADMIN和delegated挂载,并在本地包composer.json中声明"options":{"symlink":true}。

本地包调试必须和线上配置物理隔离,不能靠注释/条件判断或环境变量开关 repositories —— Composer 不解析 PHP 逻辑,repositories 是纯 JSON 结构,任何动态写法都会直接报错或静默失效。唯一安全、可复现、不污染线上部署的方式,是把本地调试配置拆到独立文件,并通过 COMPOSER 环境变量临时加载。
用 COMPOSER 环境变量切换 composer.json 文件
Composer 原生支持通过 COMPOSER 环境变量指定配置文件路径,它优先级高于默认的 composer.json,且完全不影响主配置文件内容。
- 在项目根目录新建
composer.local.json,只放调试所需内容:{ "repositories": [ { "type": "path", "url": "../my-utils" } ], "require": { "my-vendor/my-utils": "dev-main" } } - 开发时运行:
COMPOSER=composer.local.json composer install或COMPOSER=composer.local.json composer require my-vendor/my-utils:dev-main - 线上部署仍用原命令:
composer install --no-dev,完全不感知composer.local.json - 把这个文件加进
.gitignore,确保不会误提交
为什么不能用 extra 或 config.platform 模拟本地仓库
extra 和 config.platform 都不参与包发现流程,它们只影响安装后的行为(如版本约束解析、平台兼容性检查),对 repositories 的注册毫无作用。
- 写
"extra": {"repositories": [...]}→ Composer 完全忽略,composer show --all里根本看不到你的包 - 改
config.platform.repos→ 语法错误,Composer 启动就报JSON decode error - 试图用
COMPOSER_DEV_MODE=0关闭本地仓库 → 无效,该变量只控制require-dev是否安装,不影响repositories加载
Windows / Docker 下 symlink 失效的硬性补救
即使 composer.local.json 配置正确,Windows 或 Docker 容器里仍可能 fallback 到 copy 模式,导致改代码不生效 —— 这不是配置问题,是系统能力限制。
- Windows 必须以管理员身份运行终端,否则
symlink创建失败且无提示 - Docker 需同时满足两个条件:启动容器时加
--cap-add=SYS_ADMIN,且挂载本地包目录时用-v /host/path:/container/path:delegated(不能用cached) - 最关键的一步:本地包自己的
composer.json中必须声明"options": {"symlink": true},主项目配了没用 - 验证是否真用了 symlink:
dir vendor\my-vendor\my-utils(Windows)看到JUNCTION字样才算成功;Linux/macOS 用ls -la看箭头指向
最易被忽略的一点:所有路径都必须相对于 composer.local.json 所在位置,而不是项目根目录下的 composer.json —— 如果你把 composer.local.json 放在子目录里,../my-utils 就会错一层。调试前先确认当前工作目录和文件位置关系。


















