You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Yii2中验证二维数组的name与email字段?

嘿,这个问题我刚好有实操经验,在Yii2里验证这类二维数组的字段其实不难,主要用each验证器配合子模型或者嵌套规则就能搞定,下面给你两种常用的实现方式:

方法一:使用子模型验证(推荐,可复用性高)

这种方式适合后续可能需要单独复用乘客字段验证逻辑的场景,先创建一个专门的子模型来定义单个乘客的验证规则:

class PassengerItem extends \yii\base\Model
{
    public $name;
    public $email;

    public function rules()
    {
        return [
            // 验证name和email必填
            [['name', 'email'], 'required', 'message' => '{attribute}不能为空'],
            // 限制name的长度
            ['name', 'string', 'max' => 100, 'message' => '姓名不能超过100个字符'],
            // 验证邮箱格式
            ['email', 'email', 'message' => '请输入有效的邮箱地址'],
        ];
    }
}

接着在主表单模型(比如PassengerForm)里,用each验证器结合ModelValidator来批量验证二维数组里的每个元素:

class PassengerForm extends \yii\base\Model
{
    public $passengers; // 对应你的二维数组

    public function rules()
    {
        return [
            // 先确保passengers是必填的数组
            ['passengers', 'required', 'message' => '乘客信息不能为空'],
            ['passengers', 'each', 'rule' => [
                'class' => \yii\validators\ModelValidator::class,
                'modelClass' => PassengerItem::class,
            ]],
        ];
    }
}
方法二:直接嵌套验证规则(无需额外模型)

如果只是临时验证,不想创建子模型,也可以直接在主模型里用嵌套的each验证器或者自定义内联验证:

方式A:嵌套each验证器

class PassengerForm extends \yii\base\Model
{
    public $passengers;

    public function rules()
    {
        return [
            ['passengers', 'required'],
            ['passengers', 'each', 'rule' => [
                // 针对每个子数组,验证内部的name和email字段
                'attributes' => ['name', 'email'],
                'rules' => [
                    [['name', 'email'], 'required'],
                    ['name', 'string', 'max' => 100],
                    ['email', 'email'],
                ],
            ]],
        ];
    }
}

方式B:自定义内联验证(更灵活)

这种方式适合需要自定义复杂验证逻辑的场景:

class PassengerForm extends \yii\base\Model
{
    public $passengers;

    public function rules()
    {
        return [
            ['passengers', 'required'],
            // 自定义内联验证规则
            ['passengers', function ($attribute, $params) {
                if (!is_array($this->$attribute)) {
                    $this->addError($attribute, '乘客信息必须是数组格式');
                    return;
                }

                foreach ($this->$attribute as $index => $passenger) {
                    // 验证name字段
                    if (empty($passenger['name'])) {
                        $this->addError("{$attribute}[{$index}][name]", '第'.($index+1).'位乘客姓名不能为空');
                    } elseif (strlen($passenger['name']) > 100) {
                        $this->addError("{$attribute}[{$index}][name]", '第'.($index+1).'位乘客姓名不能超过100字符');
                    }

                    // 验证email字段
                    if (empty($passenger['email'])) {
                        $this->addError("{$attribute}[{$index}][email]", '第'.($index+1).'位乘客邮箱不能为空');
                    } elseif (!filter_var($passenger['email'], FILTER_VALIDATE_EMAIL)) {
                        $this->addError("{$attribute}[{$index}][email]", '第'.($index+1).'位乘客邮箱格式无效');
                    }
                }
            }],
        ];
    }
}
如何使用验证逻辑

在控制器里,你可以像普通模型一样加载数据并验证:

public function actionSubmitPassengers()
{
    $model = new PassengerForm();
    
    if ($model->load(Yii::$app->request->post()) && $model->validate()) {
        // 验证通过,处理乘客数据逻辑
        return $this->redirect(['success']);
    }

    // 验证失败,返回表单或错误信息
    return $this->render('submit', ['model' => $model]);
}
错误信息的显示

如果验证失败,错误信息会被存储在$model->errors中,你可以在视图里这样展示:

<?php if ($model->hasErrors()): ?>
    <div class="alert alert-danger">
        <?php foreach ($model->getErrors() as $field => $messages): ?>
            <?php foreach ($messages as $message): ?>
                <p><?= $message ?></p>
            <?php endforeach; ?>
        <?php endforeach; ?>
    </div>
<?php endif; ?>

内容的提问来源于stack exchange,提问作者Bell Carson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:05:06