必须先引入vendor/autoload.php,否则自动加载机制完全失效;它不定义类,而是通过spl_autoload_register()注册PSR-4、classmap、files等加载逻辑到PHP autoload队列,若在new类之后才引入,PHP因队列为空直接报Class not found。

必须先 require vendor/autoload.php,否则所有 autoload 配置都无效。 这不是可选步骤,而是启动整个加载链的开关。PHP 在类未定义时触发 autoload 机制,但若没注册任何 handler,就直接报 Class not found —— 它不会提示“你忘了引 autoload”,只会沉默失败。
为什么 require 'vendor/autoload.php' 必须写在第一行
因为 vendor/autoload.php 不是“定义类”的文件,而是执行注册动作的入口:它立即调用 ClassLoader::getLoader(),内部通过 spl_autoload_register() 把 PSR-4、classmap、files 等多个加载逻辑挂进 PHP 的 autoload 队列。
常见错误现象:
- 入口文件里先
new AppController(),再require vendor/autoload.php→ 必定失败 - CLI 脚本漏掉这行,却在测试中“偶然”跑通(因其他依赖已提前加载过该类)→ 具有迷惑性
- 用了
set_include_path()或自定义__autoload且返回false→ 拦截了后续 Composer 加载器
PSR-4 映射表从哪来、怎么生效
映射数据不在 vendor/autoload.php 里,而在 vendor/composer/autoload_psr4.php 这类生成文件中。它本质是一个 PHP 数组,形如:['App\' => ['src/']] 。
关键约束:
- 命名空间必须以反斜杠结尾,写成
"App\"(JSON 中双反斜杠是转义,实际值仍是单反斜杠)才合法;写成"App"就完全不匹配 - 路径末尾必须带斜杠,
"src/"和"src"在拼接时行为不同:src/Controller/Home.phpvssrcController/Home.php - 类名
App\Controller\Home剥离前缀后得Controller\Home,再按\替换为/得Controller/Home,最后拼上src/→src/Controller/Home.php - 文件名必须与末级类名严格一致,
Home.php里不能定义class home(Linux 下大小写敏感)
改了 composer.json 或加了新类,为什么还是 Class not found
根本原因是映射表没更新。你改的是配置源,不是运行时数据。vendor/autoload.php 只是启动器,真正干活的是它加载的 autoload_psr4.php 等文件 —— 它们不会监听文件变化,只在 composer dump-autoload 时重写。
必须手动执行:
-
composer dump-autoload:重新扫描并生成映射 -
composer dump-autoload -o:额外生成autoload_classmap.php,跳过路径推导,适合部署环境 - CI/CD 场景下注意:
composer install --no-dev会跳过autoload-dev区块,测试类在生产环境不可见
classmap 和 files 怎么选、有什么坑
classmap 适合无命名空间的老代码或第三方库;files 只用于加载纯函数、常量、全局配置等无 class 声明的 PHP 文件。
常见踩坑:
-
files列表里的路径必须是相对composer.json所在目录的,且文件必须真实存在,否则composer install会报错中断 - 别把含
exit/die的脚本放files里,它们会在 Composer 自动加载阶段执行,容易导致 CLI 命令意外退出 -
classmap配置项不支持多路径数组如["app/", "src/"],Composer 会静默忽略第二个 - 混用时加载顺序是
classmap → PSR-4 → files,但files是预加载,不参与“按需加载”流程
最易被忽略的一点:所有路径和命名空间的斜杠方向、结尾是否带斜杠、大小写,全部是硬匹配。Windows 下开发时看似正常,一上 Linux 就崩,往往就卡在这几个字符上。











