yii2将url中的短横线(-)转为驼峰并添加controller后缀映射控制器类名,如/user-profile/index→userprofilecontroller;类名、文件名、路径须严格匹配且大小写敏感。

Yii2 中 URL 里的 - 怎么映射到控制器类名?
Yii2 默认把 URL 路径中的短横线(-)转成驼峰,再拼上 Controller 后缀去查类。比如访问 /user-profile/index,框架会去找 UserProfileController 类——不是 User-ProfileController,也不是 UserControllerProfile。
这个转换由 yii\web\UrlManager::convertPathToRoute() 触发,底层调用 yii\helpers\Inflector::id2camel()。它只处理路径段,不碰查询参数或后缀。
- 路径段
user-profile→UserProfile - 路径段
api-v1-posts→ApiV1Posts(注意:连续大写保留,V1不会变V1) - 路径段
admin-user-list→AdminUserList,对应AdminUserListController
控制器类名必须带 Controller 后缀,且首字母大写
即使 URL 是 /site,也必须有 SiteController 类;写成 siteController 或 Sitecontroller 都会报错:Class 'app\controllers\Sitecontroller' not found。
类文件路径必须严格匹配命名空间。例如 app\controllers\UserProfileController 必须放在 @app/controllers/UserProfileController.php,不能是 user-profile-controller.php 或 userprofilecontroller.php。
- 文件名大小写敏感(Linux/macOS 下尤其关键)
- 类名中不能有下划线,
User_ProfileController会被当成User_Profile+Controller,找不到类 -
protected function init()里改$this->id不影响路由解析,只影响内部 ID
urlManager 配置里关掉自动转换会怎样?
如果在配置里设了 'enablePrettyUrl' => false,URL 变成 index.php?r=user-profile%2Findex,此时 r 参数仍走同样转换逻辑——user-profile/index 还是转成 user-profile/index 路由,再映射控制器。关掉美化只是去掉 PATH_INFO 解析,不跳过转换步骤。
真想禁用短横转驼峰,得重写 UrlManager::createController() 或替换 Inflector::id2camel() 的行为,但代价是整个路由生态可能断裂,比如 Gii 生成的链接、Url::to() 输出都会错乱。
- 修改
Inflector::id2camel()需全局生效,影响ActiveRecord表名、字段映射等其他地方 -
UrlManager::rules中显式写死'user-profile' => 'user-profile/index'可绕过转换,但控制器名仍需合法(即UserProfileController) - 别用
controllerMap把user-profile映射到user/profile,那只是路径重定向,不改变类名要求
调试时怎么看实际匹配了哪个控制器?
最直接的办法是在 web/index.php 入口加一行日志:
Yii::debug(Yii::$app->requestedRoute, __METHOD__);
请求 /user-profile/index 会输出 user-profile/index;再在 UrlManager::parseRequest() 返回前打点,能看到 ['user-profile', 'index'] → ['user-profile', 'index'] → ['user-profile', 'index'] → 最终控制器对象。
- 错误信息
Invalid Route: user-profile/index通常意味着没找到UserProfileController类,或类里没actionIndex() -
ReflectionException: Class app\controllers\UserProfileController does not exist就是文件路径/命名/大小写三者至少一个错了 - 别依赖 IDE 自动补全来判断类是否存在——它不校验真实文件系统路径











