У меня есть модель ActiveRecord User
с этим методом scenarios():
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']],
];
}
Я хочу отказаться от публикации всех данных с ключами, которые не включены в сценарий "создать" (разрешить получать только данные с ключами: "имя пользователя", "письмо", "пароль").
Сейчас я делаю это в 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);
}
...
Есть ли более элегантный способ сделать это?
Я не понимаю, в чем преимущество этого.
Пользователь может публиковать любые данные, но если он строго подтвержден, вам не о чем беспокоиться.
Если вы все же хотите его использовать, ваше решение в порядке, вот несколько замечаний:
Для получения данных $_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.");
}
}
Yii::$app->requst->post()
возвращает значенияYii::$app->requst->post()
в секции$value
, но нам нужно сравнить ключи полученных данных со значениями из activeAttributes ().