Yii2 - 验证嵌套对象 [英] Yii2 - Validating nested objects
问题描述
这是一个关于我思考了一段时间的话题的问题.
Here's a question about a topic that Ive been thinking about for a while.
在 Yii2 中,一般建议为您的请求创建表单模型.规则被添加到这些模型中以验证输入.一个例子是 Yii2 指南中的 EntryForm
In Yii2, it is recommended generally to create Form Models for your requests. Rules are added to those models to validate the input. An example is the EntryForm in the Yii2 guide
<?php
namespace app\models;
use Yii;
use yii\base\Model;
class EntryForm extends Model
{
public $name;
public $email;
public function rules()
{
return [
[['name', 'email'], 'required'],
['email', 'email'],
];
}
}
我的问题是,当我们有嵌套对象时.一个示例是用于创建具有多个分支的客户的表单.如果 Customer 和 Branch 是两个独立的模型,但都以一种形式提交,那么验证来自此类嵌套表单的输入的最佳选择是什么.请记住,这里的输入是嵌套的.示例:
My problem is, when we have nested objects. An example is a form for creating Customer with multiple Branches. If Customer and Branch are two separate models, but both get submitted in one form, what is the best option for validating input from such a nested form. Bear in mind that here the input is nested. Example:
{
"name": "customer",
"vat_no": "12345678",
"time_zone": 277,
"category": 1,
"email": "customer@mycustomer.com",
"stores":[
{
"name": "store1",
"phone": 1234567
},
{
"name": "store2",
"phone": 2345678
}
]
}
推荐答案
对于简单的情况,您可以在表单模型中使用一个模型和自定义验证器:
For simple cases you may use one model and custom validator inside of your form model:
public function rules() {
return [
// ...
['stores', 'validateStores'],
];
}
public function validateStores() {
$phoneValidator = new StringValidator(); // use real validators
$nameValidator = new StringValidator(); // use real validators
foreach ($this->stores as $store) {
if (!$phoneValidator->validate($store['phone'], $error)) {
$this->addError('stores', $error);
return; // stop on first error
}
if (!$nameValidator->validate($store['name'], $error)) {
$this->addError('stores', $error);
return; // end on first error
}
}
}
validateStores()
可以提取到单独的验证器类,然后你也可以使用 EachValidator
而不是 foreach
.
validateStores()
may be extracted to separate validator class, then you may also use EachValidator
instead of foreach
.
对于更复杂的嵌套模型,您可能应该为商店创建单独的 StoreForm
模型(因此您将拥有嵌套的表单模型),并对子项调用 validate()
.
For more complicated nested models you should probably create separate StoreForm
model for stores (so you will have nested form models), and call validate()
on children.
/**
* @var StoreForm[]
*/
public $stores;
public function rules() {
return [
// ...
['stores', 'validateStores'],
];
}
public function validateStores() {
foreach ($this->stores as $store) {
if (!$store->validate()) {
$this->addError('stores', 'Stores config is incorrect.');
return;
}
}
}
这篇关于Yii2 - 验证嵌套对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!