Yii2标准REST控制器PUT/PATCH返回200但模型未更新
问题简述
参照Yii2官方REST指南完成配置后,除PUT/PATCH请求外其余接口功能正常,更新接口返回200 OK状态码但对应模型数据实际未更新。
相关配置
- 控制器配置:创建继承REST
ActiveController的User控制器,代码如下:
namespace app\controllers; use yii\rest\ActiveController; class UserController extends ActiveController { public $modelClass = 'app\models\User'; }
- 模型规则配置:修改User模型验证规则,将相关字段设为安全属性:
public function rules() { return [ ['status', 'default', 'value' => self::STATUS_INACTIVE], ['status', 'in', 'range' => [self::STATUS_ACTIVE, self::STATUS_INACTIVE, self::STATUS_DELETED]], [['username', 'email'], 'required'], [['username', 'email'], 'unique'], ['email', 'email'], [['password_hash', 'password_reset_token', 'verification_token', 'auth_key', 'status,created_at', 'updated_at', 'password'], 'safe'], ]; }
- 路由配置:配置URL规则,同时支持单复数路径访问:
'urlManager' => [ 'enablePrettyUrl' => true, 'enableStrictParsing' => true, 'showScriptName' => false, 'rules' => [ [ 'class' => 'yii\rest\UrlRule', 'controller' => 'user', 'pluralize' => false, 'except' => ['index'], ], [ 'class' => 'yii\rest\UrlRule', 'controller' => 'user', 'patterns' => [ 'GET,HEAD,OPTIONS' => 'index', ], ], ], ]
- 请求配置:开启JSON输入解析:
'request' => [ 'parsers' => [ 'application/json' => 'yii\web\JsonParser', ] ]
测试过程中,GET/POST/DELETE等请求均正常运行,发起PATCH /users/123、PUT /users/123更新请求时,接口返回200 OK状态码,但返回的记录无任何修改痕迹:
问题原因
核心问题是模型验证规则存在笔误:
safe规则的字段列表中,status、created_at、updated_at三个字段被错误写成了一个字符串'status,created_at',框架会将其识别为一个名为status,created_at的不存在字段,直接导致status、created_at、updated_at三个字段没有被正确标记为安全属性。
Yii2 REST的更新逻辑依赖模型的批量赋值load()方法,只有当前场景下被标记为安全的字段才能被批量赋值。如果传入的更新参数中包含未标记安全的字段,这些字段值会被直接过滤;如果请求参数中没有能触发其他验证规则错误的内容,接口会正常返回200 OK状态码,但实际不会执行有效数据更新。
另外Yii2 REST默认的actionUpdate方法不会校验load()方法的返回值,即使批量赋值完全没有接收到有效字段,也会直接查询模型并返回,进一步造成“更新成功”的假象。
修复方法
修正模型rules()方法中safe规则的字段列表,把合并为单个字符串的字段拆分为独立的数组元素即可:
[['password_hash', 'password_reset_token', 'verification_token', 'auth_key', 'status', 'created_at', 'updated_at', 'password'], 'safe'],
如果修复后仍存在部分字段无法更新的情况,逐一检查对应字段的验证规则:比如unique验证在更新场景下需要排除当前记录本身,否则会触发验证失败导致保存流程中断。
内容的提问来源于stack exchange,提问作者trejder
相关产品推荐
相关产品推荐

