yii rest控制器必须继承yii\rest\activecontroller并设$modelclass,配置yii\rest\urlrule路由规则,且模型需有rules()方法;否则将出现404、空响应或400错误。

控制器类必须继承 yii\rest\ActiveController,不能用普通 Controller
Yii2 的 REST 行为(比如自动映射 GET /users 到 index 动作、自动序列化 JSON、处理 Content-Type 协商)只在 yii\rest\ActiveController 及其子类中生效。用 yii\web\Controller 写个 actionIndex(),哪怕返回 json_encode(),也不算 REST 接口——它不响应 Accept: application/json,不校验 HTTP 方法,也不触发 VerbFilter 或 ContentNegotiator。
实操要点:
- 控制器文件里
use yii\rest\ActiveController;,类定义写class UserController extends ActiveController - 必须声明
public $modelClass = 'app\models\User';,路径要完整、大小写敏感,且该类必须继承yii\db\ActiveRecord - 不要覆盖
actions()方法,除非你清楚自己在删掉哪些默认动作(index、view、create等);若覆盖,需显式调用parent::actions()并保留关键项 - 模块内控制器(如
api\modules\v1\controllers\UserController)的$modelClass仍写模型的完整命名空间,不写模块前缀,例如'api\modules\v1\models\User'或'common\models\User',不是'v1\User'
$modelClass 没设对,404 或空响应就来了
ActiveController 本身不查数据库,它靠 $modelClass 去反射调用 findModel($id)、find() 这些静态方法。如果 $modelClass 指向一个不存在的类、没继承 ActiveRecord、或类里没实现 findModel()(比如自定义了主键字段但没重写),请求就会静默失败:GET /users 返回空数组,GET /users/1 返回 404 —— 不报错,只没数据。
检查步骤:
- 确认模型类存在且可被自动加载(
var_dump(class_exists('app\models\User'));) - 确认模型继承
yii\db\ActiveRecord,并至少有一个public static function tableName() - 如果主键不是
id,必须在模型中重写public static function findModel($id),否则view和update动作会找不到记录 - 模型里必须有
rules()方法,否则 POST/PUT 请求即使数据合法,也会因验证跳过而返回 400(ActiveController默认启用验证,但不会提示缺规则)
URL 规则必须配 yii\rest\UrlRule,且顺序不能错
光有控制器不够。ActiveController 是“能力”,yii\rest\UrlRule 才是“入口”。它负责把 GET /v1/users 解析成 ['v1/user', 'index'],再交给控制器执行。常见错误是:写了自定义路由(比如 '<action>' => 'site/<action>'</action></action>)放在 urlManager->rules 前面,结果所有 REST 请求都被提前匹配、进不了 UrlRule。
正确配置要点:
-
'enablePrettyUrl' => true和'enableStrictParsing' => true必须同时开启 -
yii\rest\UrlRule实例必须放在rules数组的末尾 -
'controller' => ['v1/user']中的路径是小写、无命名空间、斜杠分隔的模块+控制器 ID,和实际类名无关(UserController对应user) - 如果模型叫
User,默认期望复数路由/users;若想用单数/user,得加'pluralize' => false配置项 - 别漏
'showScriptName' => false,否则 Apache/Nginx 重写失效时,index.php/v1/users会走默认路由,不触发 REST 行为
POST/PUT 数据为空?检查 Content-Type 和解析器
ActiveController 默认只解析 application/json 格式的请求体。如果前端用 application/x-www-form-urlencoded 发 POST(比如 jQuery $.post() 默认行为),数据会完全被忽略,$_POST 为空,模型接收不到字段,验证失败后直接返回 400。
解决方式:
- 前端发请求时显式设置
Content-Type: application/json,并确保 body 是合法 JSON 字符串(如{"name":"test"}) - 服务端确认
request组件已注册 JSON 解析器:'parsers' => ['application/json' => 'yii\web\JsonParser'],通常在config/web.php的components['request']下配置 - 如果必须支持表单编码,得手动在控制器中加解析逻辑,或改用
yii\rest\Controller自行实现动作,而不是依赖ActiveController的自动绑定
最常被忽略的是:模型层 rules() 没定义、URL 规则顺序错、以及 POST 时 Content-Type 不是 JSON —— 这三处一出问题,接口就“看起来能跑,但死活不干活”。











