autoload 配置必须写在 composer.json 的 "autoload" 字段中,vendor/autoload.php 是自动生成文件,手动修改会被覆盖;psr-4 要求命名空间与目录严格对应,classmap 扫描所有 PHP 文件生成类映射,files 列出需全局加载的函数文件;修改后必须执行 composer dump-autoload,否则新类不被识别;autoload-dev 与 autoload 独立,测试类应放 autoload-dev;vendor 目录不可通过 composer.json 配置更改,须用 COMPOSER_VENDOR_DIR 环境变量并同步更新 require 路径。

autoload 配置写在 composer.json 里,不是 vendor/autoload.php
所有自动加载规则都必须声明在项目根目录下的 composer.json 的 "autoload" 字段中,vendor/autoload.php 只是生成结果,改它没用,下次 composer install 或 dump-autoload 就会被覆盖。
常见错误是直接编辑 vendor/autoload.php 加 require_once,或试图在其中 patch 路径逻辑——这属于对抗生成机制,必然失效。
-
"psr-4":用于类,要求命名空间与目录结构严格对应,如"App\": "src/"意味着AppControllerHome必须位于src/Controller/Home.php -
"classmap":扫描指定目录下所有 PHP 文件(不管有没有命名空间),生成类名到路径的静态映射,适合老代码或无命名空间类 -
"files":列出需全局require_once的 PHP 文件(如函数库),路径相对于composer.json,不能用通配符
修改后必须手动运行 composer dump-autoload
Composer 不监听文件系统变化,也不会在 composer install 时自动重生成 autoload 映射。只要改了 composer.json 中的 "autoload",或新增/移动了类文件、改了 namespace,就必须显式执行:
composer dump-autoload
否则新类永远不被识别,报 Class not found 或 Call to undefined function。
- 开发调试阶段建议先不用
-o,避免优化版缓存掩盖路径错误 - 上线前加
-o(即composer dump-autoload -o)可显著提升加载速度,但代价是只扫描psr-4和classmap中明确声明的路径,漏一个目录,里面的新类就彻底不可见 - 如果用了
"autoload-dev"(如测试类),同样要单独执行dump-autoload,且需确认composer show -s输出中已包含你的映射项
autoload-dev 和 autoload 是两套独立配置,不能混用
"autoload-dev" 里的规则只影响开发环境,比如 PHPUnit 运行时;而 "autoload" 是生产可用的。两者互不继承、也不合并,更不会因为写了 "autoload-dev" 就让 "autoload" 自动生效。
- 测试类放进
"autoload-dev"后,必须确保测试启动前已加载vendor/autoload.php(多数测试框架默认做这事,但自定义启动脚本容易漏) - 别把
tests/bootstrap.php这种纯逻辑脚本塞进"files"——它没 class/function 声明,Composer 不会加载它,也起不到引导作用 - 若误把
Tests放进"autoload"的psr-4,用户安装你包时也会加载测试类,增大部署体积,还可能暴露内部实现
vendor 目录位置不能靠 composer.json 配置改
想换 vendor 目录?别在 composer.json 里加 "vendor-dir"——这个字段早在 Composer 2.x 就被废弃,现在写进去完全无效。
唯一受支持的方式是设置环境变量 COMPOSER_VENDOR_DIR:
COMPOSER_VENDOR_DIR="/path/to/my-vendor" composer install
但注意:vendor/autoload.php 内部是硬编码相对路径的,一旦你换了 vendor 位置,代码里 require __DIR__.'/vendor/autoload.php' 就得同步改成新路径,否则照样 Class not found。
这个细节常被忽略:autoload 机制本身不关心 vendor 在哪,但它生成的 loader 依赖于那个路径存在且可读;改了位置却不改 require,等于只搬了书架没搬书。











