Composer自动加载依赖vendor/autoload.php注册spl_autoload_register()与预生成映射表协同工作;漏引该文件或未执行composer dump-autoload,类必然找不到。

Composer自动加载不是靠“猜路径”或手写函数,而是靠 vendor/autoload.php 注册 spl_autoload_register() + 预生成的静态映射表(如 vendor/composer/autoload_psr4.php)协同工作;漏掉 require 'vendor/autoload.php' 或没跑 composer dump-autoload,类就一定找不到。
为什么 require 'vendor/autoload.php' 必须放在入口文件第一行
这行代码不是“引入一个文件”,而是立即执行注册动作:调用 ClassLoader::getLoader(),再通过 spl_autoload_register() 把 PSR-4、classmap 等加载逻辑挂进 PHP 的 autoload 队列。一旦晚于任何类使用(比如先 new AppController() 再 require),PHP 在实例化时 autoload 队列还是空的,直接报 Class not found,不给重试机会。
- 不能包在
if、函数体、try/catch里——PHP 解析到new就触发 autoload,此时作用域还没进函数 - CLI 脚本和 Web 入口(如
public/index.php)必须各自显式require,它们不共享 autoload 注册状态 - 用
include替代require_once是隐形炸弹:路径错时不报致命错误,只静默失败 - 框架(如 Laravel)若在 bootstrap 前就实例化了某个类,而
autoload.php还没引入,同样炸
PSR-4 映射中反斜杠和斜杠为什么不能省
PSR-4 不是模糊匹配,是字符串前缀截取 + 路径拼接。命名空间末尾的 和路径末尾的 / 是硬分隔锚点,缺一不可。它们共同决定“怎么剥、怎么拼”。
-
"App\": "src/"→ 类App\Controller\UserController剥离前缀得Controller\UserController,\替换为/得Controller/UserController,拼上src/→src/Controller/UserController.php -
"App": "src/"(命名空间缺)→App不被识别为有效前缀,跳过 PSR-4 查找,fallback 到 classmap 或直接失败 -
"App\": "src"(路径缺/)→ 拼成srcController/UserController.php,404 - Linux 下大小写敏感:
UserController.php里写class usercontroller,或文件名是usercontroller.php,都加载失败
改了 composer.json 为什么还是 Class not found
根本原因是映射表没更新。你改的是配置源(composer.json),但真正被加载器查的是 vendor/composer/autoload_psr4.php —— 它是静态 PHP 数组,只在 composer dump-autoload 时重写。漏掉这步,PHP 还在用旧表查路径。
-
vendor/autoload.php是启动器,不是配置文件;手动改它或autoload_psr4.php白干,下次dump-autoload直接覆盖 - CI/CD 流水线里漏掉
composer install --no-interaction或composer dump-autoload→autoload_psr4.php根本不存在或过期 - 用了
--no-scripts参数 → 自动加载相关脚本被跳过,映射文件不会生成 - 每个 PSR-4 映射项只支持一个根目录:
"App\": ["app/", "src/app/"]中第二个路径会被 Composer 静默忽略
最常被忽略的其实是“路径相对性”:"App\": "src/" 中的 src/ 是相对于 composer.json 所在目录,不是当前脚本、也不是 vendor/autoload.php;类文件名必须和末级类名严格一致(class Home 必须在 Home.php),不支持 .inc 等非 .php 后缀。











