在 Yii 2 中,更新模型时,当某字段不存在时,不更新模型(默认实现),当某字段存在,其值为空(赋值为属性的旧值)时,不更新模型的实现

1、GET http://api.channel-pub-api.localhost/qq/v1/qq-cw-apps/edit/148d4df6eba311e899f654ee75d2ebc1?group_id=spider ,响应如下,基于安全考虑,重置 Client Secret 为空字符串

{
    "code": 10000,
    "message": "编辑企鹅号的内容网站应用成功",
    "data": {
        "channel_app_source_uuid": "148d4df6eba311e899f654ee75d2ebc1",
        "penguin_name": "篮球场马达1",
        "penguin_login_qq": "3176058386",
        "penguin_login_wx": "",
        "client_id": "32deed1727f9a23a504d6dda48938de0",
        "client_secret": "",
        "permission": 2,
        "status": 0
    }
}

2、因此,PUT http://api.channel-pub-api.localhost/qq/v1/qq-cw-apps/148d4df6eba311e899f654ee75d2ebc1?group_id=spider 时,如果不更新 client_secret 的值,其值为空字符串

Body

{
 "penguin_name": "篮球场马达1",
 "penguin_login_qq": "3176058386",
 "penguin_login_wx": "",
 "client_id": "32deed1727f9a23a504d6dda48938de0",
 "client_secret": "",
 "permission": 2,
 "status": 0
}

3、请求响应失败,422,如图1

图1

{
    "code": 20004,
    "message": "数据验证失败:Client Secret不能为空。"
}

4、现在需要实现 当 client_secret 的值为空字符串时,不对 client_secret 执行验证,且不更新 client_secret 的值,编辑验证规则

    /**
     * @inheritdoc
     */    public function rules()
    {
        $rules = [
            /* 更新企鹅号的内容网站应用 */            [['client_secret'], 'validateClientSecret', 'skipOnEmpty' => false, 'on' => self::SCENARIO_UPDATE],
            [['permission'], 'in', 'range' => [self::PERMISSION_SYNC, self::PERMISSION_PUB, self::PERMISSION_SYNC_PUB], 'on' => self::SCENARIO_UPDATE],
            [['status'], 'in', 'range' => [self::STATUS_DISABLED, self::STATUS_ENABLED], 'on' => self::SCENARIO_UPDATE],
        ];
        $parentRules = parent::rules();

        return ArrayHelper::merge($rules, $parentRules);
    }

    /**
     * Validates the Client Secret.
     * This method serves as the inline validation for Client Secret.
     *
     * @param string $attribute the attribute currently being validated
     * @param array $params the additional name-value pairs given in the rule
     */    public function validateClientSecret($attribute, $params)
    {
        // 当 Client Secret 为空时,赋值 Client Secret 为原先的值
        if (empty($this->$attribute)) {
            $this->$attribute = $this->getOldAttribute($attribute);
        }
    }

5、PUT http://api.channel-pub-api.localhost/qq/v1/qq-cw-apps/148d4df6eba311e899f654ee75d2ebc1?group_id=spider 时,贵响应成功,如图2

图2


6、查看 SQL 语句,符合预期,当 client_secret 的值为空字符串时,未更新 client_secret 的值
UPDATE `cpa_qq_cw_app` SET `permission`=1, `updated_at`=1542610618 WHERE `id`=6
永夜