如何在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
相关产品推荐
相关产品推荐

