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

时间:2015-11-09 22:09:21

标签: php yii2

我的ActiveRecord模型User包含此 scenario()方法:

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

此外,此模型还有 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']],
    ];
}

我想拒绝使用未包含在 &#34;创建&#34; 方案中的密钥发布所有数据(仅允许使用密钥接收数据:< em>&#39;用户名&#39;,&#39;电子邮件&#39;,&#39;密码&#39; )。

现在我在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);
}
...

有更优雅的方法吗?

1 个答案:

答案 0 :(得分:2)

我不明白这有什么好处。

用户可以发布任何数据,但如果经过严格验证,您无需担心。

如果您仍想使用它,您的解决方案是可以的,但这里有几条评论:

  • 要获取$_POST数据,请使用高级方法\Yii::$app->request->post()(它可以返回所有数据,子数组或特定值)。在其内部调用getBodyParams()

  • 404 Page Not Found异常不适合这种情况。我认为400 Bad Request更适合。

  • 最好使用内置的Yii2包装器来处理常见异常,例如BadRequestHttpException。通过这种方式,您不必担心其代码并更多地考虑其含义。

  • activeAttributes()返回没有值的属性名称,因此您不必将foreach中的迭代元素分解为$key$value

因此,这些更改后的代码可能是这样的:

$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.");
    }
}