psr-4映射必须写在扩展包自身composer.json的顶层autoload字段中,命名空间末尾需双反斜杠(json中为"mypackage\"),路径须以/结尾(如"src/"),大小写与目录结构、类名严格一致,修改后须在扩展包根目录执行composer dump-autoload生效。

psr-4 映射必须写在扩展包的 composer.json 顶层 autoload 字段
扩展包不是项目,它的自动加载规则由自身 composer.json 控制,不能指望主项目去配。常见错误是把 "autoload": {"psr-4": {"MyPackage": "src/"}} 嵌在 require 或 extra 里,Composer 直接忽略——它只认和 name、type 并列的一级 autoload 键。
命名空间末尾必须是双反斜杠(JSON 中写作 "MyPackage\"),路径必须以 / 结尾(如 "src/"),否则拼路径时会变成 srcMyClass.php;大小写必须和实际目录、类名完全一致,Linux 下 src/Http/ 和 src/http/ 是两个路径。
- 类文件名必须与类名严格一致:
MyPackageHttpClient.php→class Client - 测试类建议单独放进
autoload-dev,避免污染主加载逻辑 - 改完后必须在扩展包根目录下运行
composer dump-autoload,不是在主项目里
开发阶段别用 composer dump-autoload -o
加 -o 会生成 autoload_classmap.php,跳过运行时命名空间→路径的拼接逻辑。这在主项目上线时有用,但在扩展包开发中反而掩盖问题:比如你把 "MyPackage\" 写成 "MyPackage",-o 后可能“看起来能加载”,其实是 classmap 碰巧扫到了那个文件,换环境或清缓存就崩。
日常验证请坚持用无参数命令:composer dump-autoload。成功后可直接检查 vendor/composer/autoload_psr4.php 是否包含你的映射项,比如 'MyPackage' => array($vendorDir . '/myvendor/mypackage/src')。
工作流任务拆解与模型编排技能。使用场景:(1) 收到复杂工作任务需要拆解为可执行步骤,(2) 需要为不同步骤选择最合适的模型,(3) 需要跟踪工作流进度和模型使用情况,(4) 长时间任务卡住需要问题诊断和解决方案。
- 如果没出现,说明配置位置错、格式错,或路径不存在
- 扩展包被 require 进主项目后,主项目的
vendor/autoload.php会自动合并你的 psr-4 规则,无需额外操作 - 但若你在扩展包里用了
files加载函数,主项目测试时需确保已加载vendor/autoload.php(PHPUnit 默认做,自定义启动脚本容易漏)
如何让扩展包支持多命名空间并存
一个扩展包常需暴露多个根命名空间,比如同时提供核心类 MyPackage 和 Facade MyPackageFacades,或者兼容旧版的 Legacy。不要试图用子命名空间“套娃”,直接平级声明多个 psr-4 条目即可:
"autoload": {
"psr-4": {
"MyPackage\": "src/",
"MyPackage\Facades\": "src/Facades/",
"Legacy\": "legacy/"
}
}
每条映射都独立生效,Composer 按前缀长度降序匹配(MyPackage\Facades\ 优先于 MyPackage\),无需担心覆盖。但注意:Legacy\ 这种宽前缀要放在后面,否则可能误吞 MyPackageLegacy 的类。
- 所有路径必须真实存在,哪怕空目录也要建好(如
legacy/) - 如果
Legacy\下全是无命名空间的老代码,改用classmap更稳妥 - 新增命名空间后,必须重新运行
composer dump-autoload,否则主项目composer update不会感知
扩展包里怎么排除测试类或废弃文件
Composer 2.2+ 支持 exclude-from-classmap,但它只对 classmap 生效,且必须写在 autoload 或 autoload-dev 下。如果你在扩展包里用了 classmap 扫描 tests/ 或 examples/,又不想这些文件被主项目加载,可以这样排除:
"autoload": {
"classmap": ["src/", "tests/"],
"exclude-from-classmap": ["tests/", "examples/"]
}
路径是相对于扩展包根目录的,必须带尾部 /(如 "tests/"),不支持通配符,大小写敏感。但要注意:如果同一文件既被 psr-4 又被 classmap 扫到,exclude-from-classmap 只影响 classmap 那条路径,不影响 psr-4 加载。
- 更干净的做法是把测试类全放
autoload-dev,主项目composer install --no-dev时自然过滤 - 排除后仍被加载?检查是否被框架(如 Laravel 的服务提供者)预加载,或 OPCache 缓存未刷新
- 想彻底禁用某个命名空间?Composer 不提供该能力,得从调用方代码里删掉
new LegacyOldClass()这类硬引用










