yii - Yii2 - 验证嵌套对象
问题描述
这是一个关于我已经思考了一段时间的话题的问题。
在 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'],
];
}
}
我的问题是,当我们有嵌套对象时。一个示例是用于创建具有多个Branches的Customer的表单。如果Customer和Branch是两个独立的模型,但都以一个表单提交,那么验证来自这种嵌套表单的输入的最佳选择是什么。请记住,这里的输入是嵌套的。例子:
{
"name": "customer",
"vat_no": "12345678",
"time_zone": 277,
"category": 1,
"email": "customer@mycustomer.com",
"stores":[
{
"name": "store1",
"phone": 1234567
},
{
"name": "store2",
"phone": 2345678
}
]
}
解决方案
对于简单的情况,您可以在表单模型中使用一个模型和自定义验证器:
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;
}
}
}
推荐阅读
- google-visualization - 如何使用 google.visualization lib 获取对象?
- vue.js - 多个复选框上的 vuejs v-model
- regex - sed 匹配多行范围并替换
- angular - 从 Angular 4 项目中的另一个域加载 wordpress?
- ios - 错误:未知的应用程序扩展“。” - 预期的“.app”或“.ipa”
- react-native - React Native WebView - 仅在用户交互的情况下在外部浏览器中打开链接
- python - Python将输入文件中的行/单词拆分为变量
- excel - VBA Date + TimeValue 不返回时间
- c++ - cpp 函数,根据模板类型返回值
- spring-boot - 如果我想保存以下类型的 JSON 对象,如何在 Java 中构造 DTO。使用杰克逊