PSR-4自动加载生效需满足两个硬性条件:目录结构严格匹配命名空间层级,且composer.json中映射路径必须指向实际存在的目录;键名须以\结尾,路径为相对路径,大小写敏感,文件名须符合PascalCase。

Composer 的 PSR-4 自动加载不是“配置出来就自动生效”的魔法,它依赖两个硬性条件:目录结构必须严格匹配命名空间层级,且 composer.json 中的映射必须指向**实际存在的目录路径**。配错一个斜杠或少一层 src,class not found 就立刻报给你看。
psr-4 键值对怎么写才不报错
PSR-4 映射是「命名空间前缀 → 物理目录」的键值对,注意三点:
- 键名(命名空间)必须以
\结尾,比如"App\\": "src/App/",漏掉反斜杠会触发 Composer 警告甚至加载失败 - 值(路径)是相对于
composer.json所在位置的相对路径,不能用绝对路径,也不能以/开头 - 路径末尾推荐加
/(虽非强制),避免和同名文件混淆;但若目录不存在,composer dump-autoload不报错,运行时才Class not found
{
"autoload": {
"psr-4": {
"App\\": "src/App/",
"Tests\\": "tests/"
}
}
}
自定义命名空间时 src 目录放哪、叫什么名
PSR-4 对 src 这个目录名没有强制要求,你可以叫 lib、app 甚至 banana——只要路径写对。但必须满足:命名空间每一段对应目录中的一级子目录。
例如你声明了 "MyPackage\\Http\\": "src/Http/",那么:
-
MyPackage\Http\Request类必须放在src/Http/Request.php -
MyPackage\Http\Middleware\Auth必须是src/Http/Middleware/Auth.php - 如果类文件不在对应路径下,哪怕
composer dump-autoload成功,运行时也找不到类
为什么 vendor/autoload.php 引入后还是 Class not found
常见原因不是 Composer 配置错,而是开发时疏忽:
- PHP 文件里没写
namespace,或写的 namespace 和 PSR-4 键名不一致(大小写敏感!App\≠app\) - 类文件名不符合 PascalCase 规范,比如
user_controller.php放了UserController类——PSR-4 要求文件名 = 类名 +.php - 执行了
composer install但没运行composer dump-autoload(尤其改过autoload后) - 用了
require_once 'xxx.php'手动引入,绕过了自动加载机制,导致命名空间失效
多命名空间共存与排除测试文件
一个项目可以同时定义多个 PSR-4 命名空间,互不干扰。如果不想把 tests/ 下的类加入生产自动加载,可单独用 autoload-dev:
{
"autoload": {
"psr-4": {
"App\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"App\\Tests\\": "tests/"
}
}
}
这样 composer install --no-dev 就不会把测试命名空间写进 vendor/composer/autoload_psr4.php,减少生产环境体积。
最常被忽略的是命名空间结尾的反斜杠和目录真实存在性——这两处出问题,其他都白搭。










