Yii REST资源控制器需同时配置模型类、继承yii\rest\ActiveController、注册yii\rest\UrlRule,缺一即导致404或500;URL映射依赖显式规则而非命名猜测,$modelClass须填完整命名空间字符串,版本隔离需分设模块路径与UrlRule。

直接说结论:Yii REST 资源控制器不是“写出来就能用”,必须配对三件事——模型类、控制器继承 yii\rest\ActiveController、URL 规则用 yii\rest\UrlRule;漏掉任意一个,GET /users 这类请求就会 404 或 500。
为什么继承 ActiveController 后还报错 “Class not found” 或 “No route”
常见现象是控制器文件已建好、$modelClass 也写了,但访问 /users 直接 404。根本原因是 Yii 没法自动把 URL 映射到你的控制器——它不靠文件名或命名空间猜,而是靠 urlManager 的 UrlRule 显式绑定。
-
urlManager配置里没加['class' => 'yii\rest\UrlRule', 'controller' => 'user'],就等于没注册这个资源 -
'controller' => 'user'对应的是控制器 ID(即类名去掉Controller后缀、小写首字母),不是类全名;写成'user-controller'或'app\controllers\UserController'都会失败 - 如果控制器在模块里(比如
api\modules\v1\controllers\UserController),controller值得写成'v1/user',且模块必须已在modules配置中声明
ActiveController 的 $modelClass 怎么填才不踩坑
这个属性不是可选的,也不支持运行时推导。填错会导致 Call to a member function find() on null 或 Class 'xxx' not found。
- 必须是带完整命名空间的字符串,例如
'app\models\User',不能写User::class(PHP 常量在配置数组里不解析) - 类必须真实存在,且继承自
yii\db\ActiveRecord;如果模型用了 traits 或自定义基类,只要最终是 AR 实例就行 - 若模型在模块内(如
api\modules\v1\models\User),$modelClass就得写全,别漏掉api\或v1\段 - 不建议在控制器里重写
findModel()来绕过$modelClass——除非你真要换查询逻辑,否则破坏了 REST 自动化机制
URL 规则里 yii\rest\UrlRule 的关键参数有哪些
这个规则类默认开启全部 CRUD 动作,但实际项目中常要微调。几个最常改的参数:
-
'pluralize' => true(默认):把usercontroller 映射到/users;设为false则变成/user,适合单例资源 -
'only' => ['index', 'view']:只暴露列表和详情,禁用创建/更新/删除 -
'except' => ['delete']:保留其他动作,唯独关掉删除 -
'tokens' => ['{id}' => '<id:>']</id:>:限制 ID 必须为数字,避免/users/abc触发错误查询 - 不要手动加
'prefix' => 'api';应该用urlManager的全局baseUrl或 Nginx/Apache 重写处理前缀,否则容易和模块路径冲突
版本控制下怎么让 v1/user 和 v2/user 各走各的模型
很多人以为改 $modelClass 就行,结果 v2 接口返回的还是 v1 的数据——因为没隔离模型类加载路径。
- 每个版本模块(如
api\modules\v1\Module)的init()里,要显式设置Yii::setAlias('@v1', __DIR__);,并在模型命名空间里用v1\models\User - v1 控制器的
$modelClass = 'api\modules\v1\models\User';,v2 控制器对应写v2,不能共用common\models\User(除非你真想共享逻辑) -
urlManager中两条规则要分开写:['class'=>'yii\rest\UrlRule','controller'=>'v1/user']和['class'=>'yii\rest\UrlRule','controller'=>'v2/user'],不能靠一个 rule 匹配多个版本 - 别在
common\models下放带业务逻辑的模型;版本差异大时,模型字段、验证规则、关联关系都可能不同,硬复用反而更难维护
真正麻烦的不是写代码,而是模型类路径、控制器 ID、URL 规则这三者的命名一致性——打错一个字母,调试时看到的错误信息往往不直接指向根源。


















