Yii2 - 验证嵌套对象 [英] Yii2 - Validating nested objects

查看:33
本文介绍了Yii2 - 验证嵌套对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个关于我思考了一段时间的话题的问题.

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'],
        ];
    }
}

我的问题是,当我们有嵌套对象时.一个示例是用于创建具有多个分支客户的表单.如果 CustomerBranch 是两个独立的模型,但都以一种形式提交,那么验证来自此类嵌套表单的输入的最佳选择是什么.请记住,这里的输入是嵌套的.示例:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆