这是一个关于我一直在考虑的话题的问题。
在Yii2中,建议通常为您的请求创建表单模型。将规则添加到这些模型以验证输入。一个例子是Yii2指南中的EntryForm
<?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'],
];
}
}
我的问题是,当我们有嵌套对象时。一个示例是使用多个分支创建客户的表单。如果客户和分支是两个单独的模型,但两者都以一种形式提交,那么验证来自此类嵌套表单的输入的最佳选项是什么。请记住,输入是嵌套的。示例:
{
"name": "customer",
"vat_no": "12345678",
"time_zone": 277,
"category": 1,
"email": "customer@mycustomer.com",
"stores":[
{
"name": "store1",
"phone": 1234567
},
{
"name": "store2",
"phone": 2345678
}
]
}
答案 0 :(得分:1)
对于简单的情况,您可以在表单模型中使用一个模型和自定义验证器:
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
。
对于更复杂的嵌套模型,您可能应该为商店创建单独的StoreForm
模型(因此您将拥有嵌套的表单模型),并在子项上调用validate()
。
/**
* @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;
}
}
}