require 'vendor/autoload.php' 必须放在入口文件第一行,否则因自动加载队列未注册导致 Class not found;其本质是调用 spl_autoload_register() 注册 PSR-4/classmap/files 加载逻辑。

require 'vendor/autoload.php' 必须写在入口文件第一行,否则类一定加载失败——这不是建议,是机制硬约束。
为什么 require 'vendor/autoload.php' 必须放在第一行
这行代码不定义类,只干一件事:调用 ClassLoader::getLoader(),把 PSR-4、classmap、files 三类加载逻辑通过 spl_autoload_register() 注册进 PHP 的自动加载队列。一旦你在它前面写了 new AppController(),PHP 就会立刻触发 autoload 队列——但此时队列还是空的,直接抛 Class not found。
- 常见错误:入口文件里先
new类、再require autoload.php→ 必定失败 - 更隐蔽的坑:框架启动前用了
set_include_path()或自定义__autoload()并返回false→ 后续 Composer 加载器被拦截 - CLI 脚本里漏掉这行却“偶然”跑通?大概率是其他依赖已提前加载过该类,别信这个假象
PSR-4 映射表从哪来、怎么拼出文件路径
映射数据不在 vendor/autoload.php 里,而在 vendor/composer/autoload_psr4.php 这类生成文件中。它本质是一个 PHP 数组,比如:['App' => ['src/']]。每次执行 composer dump-autoload,Composer 就扫描 composer.json 中的 autoload.psr-4 字段,硬绑定命名空间前缀和路径。
- 命名空间必须以反斜杠结尾:
"App\"合法,"App"(无反斜杠)完全不匹配 - 路径末尾必须带正斜杠:
"src/"正确,"src"会导致拼成srcController/Home.php而非src/Controller/Home.php - 类名
App\Controller\Home剥离前缀后得Controller\Home,再把\替换成/→Controller/Home.php,最后拼上src/→src/Controller/Home.php - 文件名必须与末级类名严格一致(大小写敏感):
Home.php里只能定义class Home,写成class home或文件叫home.php,Linux 下直接失败
改了 composer.json 或加了新类,为什么还是 Class not found
根本原因是映射表没更新。你改的是配置源,不是运行时数据。vendor/autoload.php 只是启动器,真正干活的是它加载的 autoload_psr4.php 等静态映射文件——它们不会监听变化,只在 composer dump-autoload 时重写。
- 新增了
src/Service/Logger.php?不执行composer dump-autoload,映射表里就没有这条记录,必然Class not found - 把
"App\": "src/"改成"App\": "app/"?不执行命令,旧映射仍指向src/,所有类都加载失败 - CI/CD 流水线里跳过这步(比如用了
--no-scripts)?检查vendor/composer/autoload_psr4.php是否存在、内容是否含你的新路径 - 手动改过
autoload_psr4.php?下次dump-autoload会直接覆盖掉
classmap 和 files 的使用边界在哪
classmap 适合无命名空间的老代码、第三方库,或你明确想用 O(1) 查找加速的场景;files 只用于加载纯函数、常量、全局配置等无 class 声明的 PHP 文件。
-
files列表写在composer.json的"autoload": {"files": ["src/helpers.php"]},路径相对于composer.json所在目录 - 多个文件按数组顺序
require_once,注意函数重定义风险(如两个文件都定义了str_slug()) -
files和类自动加载无关,不能用来加载class;反过来,也别把类文件塞进files,会触发Cannot declare class X, because the name is already in use - 改完
files列表,必须运行composer dump-autoload,否则新增的文件不会被注册
最易被忽略的点:composer dump-autoload 不是“刷新缓存”,而是重生成映射表;require 'vendor/autoload.php' 不是“引入一个工具”,而是启动整个 autoload 队列——这两步缺一不可,且顺序不能颠倒。


















