简体   繁体   English

Yii2允许仅发布模型场景中的数据

[英]Yii2 allow post only data from model's scenario

I have ActiveRecord model User with this scenarios() method: 我有ActiveRecord模型的User使用以下场景()方法:

public function scenarios()
{   
    $scenarios = parent::scenarios();
    $scenarios['create'] = ['username', 'email', 'password']; 
    return $scenarios;
}

Also, this model has rules() method: 另外,此模型具有rules()方法:

public function rules()
{
    return [
        ['username', 'required', 'on' => ['create']], 
        ['username', 'string', 'min' => 3, 'max' => 55],
        ['email', 'required', 'on' => ['create']],
        ['email', 'email', 'on' => ['create']],
        ['password', 'required', 'on' => ['create']],
        ['password', 'string', 'min' => 6, 'on' => ['create']],
    ];
}

I want to deny post all data with keys that are not included in the "create" scenario (allow receive only data with keys: 'username', 'email', 'password' ). 我想拒绝使用“创建”方案中未包含的键发布所有数据(仅接收包含键的数据: 'username','email','password' )。

Right now i do it in UserController so: 现在我在UserController这样做:

...  
$activeAttributes = $model->activeAttributes();
$postParams = Yii::$app->getRequest()->getBodyParams();

foreach($postParams as $key=>$value){
  if(!(in_array($key, $activeAttributes))) throw new \yii\web\HttpException(404, 'Invalid attribute:' . $key);
}
...

Is there a more elegant way to do this? 有没有更优雅的方法可以做到这一点?

I don't understand what's the advantage of that. 我不明白这样做的好处是什么。

The user can post any data, but if it's strictly validated you have nothing to worry about. 用户可以发布任何数据,但是如果经过严格验证,则无需担心。

If you nevertheless want to use it, your solution is OK, here are several remarks though: 如果仍然要使用它,您的解决方案就可以了,不过这里有几点建议:

  • For getting $_POST data use high level method \\Yii::$app->request->post() (it can return either all data, subarray or specific value). 为了获取$_POST数据,请使用高级方法\\Yii::$app->request->post() (它可以返回所有数据,子数组或特定值)。 getBodyParams() is called inside of it. getBodyParams()被调用。

  • 404 Page Not Found Exception is not suitable for this situation. 404 Page Not Found异常不适用于这种情况。 I think 400 Bad Request fits more. 我认为400 Bad Request更合适。

  • It's better to use built-in Yii2 wrappers for common exceptions, such as BadRequestHttpException . 最好将内置的Yii2包装器用于常见异常,例如BadRequestHttpException This way you don't worry about its code and thinking more about its meaning. 这样,您不必担心其代码,也不必担心其含义。

  • activeAttributes() returns attribute names without values so you don't have to break iterated element in foreach into $key and $value . activeAttributes()返回不带值的属性名称,因此您不必将foreach中的迭代元素分为$key$value

So the code after these changes can be something like this: 因此,这些更改之后的代码可能是这样的:

$model = new YourModel(['scenario' => YourModel::SCENARIO_CREATE]);
$activeAttributes = $model->activeAttributes();

foreach (\Yii::$app->requst->post() as $attribute => $value) {
    if (!in_array($attribute, $activeAttributes)) {
        throw new BadRequestHttpException("Invalid attribute: $attribute.");
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM