PSR-4自动加载将类名(如AppControllersUserController)按命名空间前缀与目录映射转为路径(如src/Controllers/UserController.php),需严格对齐命名空间、物理路径和composer.json配置,缺一不可。

手动 include 或 require 类文件不是错,但一旦项目变大、目录变深、命名不统一,就会卡在“类找不到”上反复调试——这不是你代码写得不对,是加载机制没对齐 PHP 的自动加载规范。
PSR-4 自动加载到底映射什么?
PSR-4 不是魔法,它只做一件事:把类名(如 AppControllersUserController)按命名空间前缀和目录的映射规则,转成对应路径(如 src/Controllers/UserController.php)。它不扫描文件,也不猜位置,全靠你写的配置。
- 前缀必须以
结尾(例如"App\"),少一个反斜杠就完全不匹配 - 映射的目录路径是相对于
composer.json所在位置的,不是相对于入口脚本 - 类名中每个
都会转为目录分隔符,但前缀部分会被直接砍掉,不参与拼接
composer.json 里怎么写才不报 Class not found?
最常见错误是路径写成绝对路径、漏掉末尾反斜杠、或 src 目录实际不存在。正确写法示例:
{
"autoload": {
"psr-4": {
"App\": "src/"
}
}
}
写完后必须运行 composer dump-autoload(开发中可加 -o 生成优化后的类映射,但调试阶段建议先不用)。
- 如果类文件放在
src/Controllers/HomeController.php,类声明必须是namespace AppControllers; - 不要在
src/下再建一层App/目录——PSR-4 已经把App\前缀剥离了,重复会导致路径变成src/App/Controllers/... - 修改
composer.json后忘记执行dump-autoload,Composer 就永远读不到新配置
为什么 new UserController() 还是报错?检查这三处
自动加载生效 ≠ 类一定能实例化。很多问题出在加载之后:
- 类文件里没有
class UserController,而是写了class UserController extends BaseController但BaseController本身没被 autoload(比如它在另一个命名空间且没配映射) - PHP 版本低于 7.4,而类用了属性类型声明(
public string $name;),解析失败导致整个文件 require 失败,autoload 就静默终止 - 文件编码不是 UTF-8 无 BOM,Windows 下用记事本保存容易混入 BOM,PHP 解析时抛出
ParseError,autoload 捕获后直接跳过
PSR-4 看似简单,真正卡住人的往往不是配置语法,而是命名空间声明、物理路径、composer.json 映射这三者的严格对齐——差一个字符、多一层目录、少一次 dump,都会让 new 变成 Class not found。











