path类型仓库是唯一支持本地调试的方案,因其绕过版本校验、启用符号链接、直连源码路径;需满足type为"path"、url为绝对路径、本地包含合法composer.json三条件。

必须用 path 类型仓库,其他方式改代码不生效、类加载失败、调试断点错位——这不是配置问题,是机制限制。
为什么 path 仓库是唯一靠谱的本地调试方式
Composer 默认所有包都走远程解析 + 压缩包解压或 Git 克隆,path 是唯一能绕过版本校验、跳过网络拉取、强制启用符号链接(或目录映射)的类型。它让 Composer 把你的本地目录“当真包用”,autoload 映射直接指向源码路径,而不是 vendor 里的副本。
常见踩坑点:
-
composer require vendor/name:@dev指向 Git 仓库?改完代码要git commit && git push && composer update才生效,根本不是本地调试 - 手动把代码拖进
vendor/?autoload.php不认这个路径,class_exists()返回false - 用
composer global require?和当前项目autoload-dev、PHP 版本、扩展完全脱钩,phpunit直接报错
path 仓库配置的三个硬性条件
缺一不可,少一个就静默忽略,composer config repositories 里压根看不到你配的项。
-
type字段必须是"path"(不是"package",也不是漏写) -
url必须是**绝对路径**:/home/user/my-pkg✅,../my-pkg❌,~/my-pkg❌,/home/user/my-pkg/❌(末尾不能有/) - 该路径下必须存在合法的
composer.json:语法正确、name字段完整、无尾逗号、全双引号
推荐写法(Linux/macOS):
composer config repositories.mypkg '{"type":"path","url":"'$(realpath ../my-pkg)'"}'
本地包 composer.json 的关键字段
主项目只管“找得到”,但能不能加载、断点能不能打进去,全看本地包自己怎么写。
-
name必须和主项目require中的字符串**逐字一致**:"acme/utils"≠"Acme/utils"≠"acme_utils" - 加
"options": {"symlink": true}—— 这句必须写在**本地包自己的composer.json里**,不是主项目的;没它,Windows 和 Docker 下默认 fallback 到 copy -
autoload和autoload-dev要写对:PSR-4 映射末尾必须带反斜杠,比如"Acme\": "src/";tests/下的测试类要用"Acme\Tests\": "tests/",少一层命名空间就加载失败 - 改完
autoload-dev后,必须手动跑:composer dump-autoload --dev,否则vendor/composer/autoload_dev.php不更新
验证是否真生效,别只看 vendor/ 目录
很多问题表面是“类找不到”,其实是 symlink 没建起来,或者 autoload 映射没刷进去。
- Linux/macOS:
ls -la vendor/acme/utils—— 看到箭头->才是 symlink;如果是普通文件夹,说明 fallback 成 copy 了 - Windows:
dir vendorcmeutils—— 看到JUNCTION或SYMLINKD才对 - 执行:
php -r "echo class_exists('Acme\Calculator') ? 'ok' : 'fail';"—— 输出ok才说明生产 autoload 生效 - Xdebug 断点要打在真实磁盘路径上,IDE 的路径映射必须和
readlink输出的源路径一致,否则断点永远不触发
最隐蔽的问题:路径对了、symlink 建了、autoload 也 dump 了,但 IDE 调试时断点灰掉——八成是 IDE 没把 symlink 源路径加进 project roots,或者 PHPStorm 的 “Resolve symlinks” 选项没开。


















