本文介绍了Yii2:ActiveForm:在一个字段上组合规则/多重验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

登录表单:

公共函数规则(){返回 [//用户名和密码都需要[['用户名', '密码'], '必填'],//用户名应该是一个数字和 8 位数字[['username'], 'number', 'message'=>'{attribute} 必须是数字'],[['用户名'], '字符串', '长度' =>8],//密码由validatePassword() 验证['密码','验证密码'],];}/*** 验证密码.* 此方法用作密码的内联验证.** @param string $attribute 当前正在验证的属性* @param array $params 规则中给出的附加名称-值对*/公共函数validatePassword($attribute, $params){如果 (!$this->hasErrors()) {$user = $this->getUser();if (!$user || !$user->validatePassword($this->password)) {$this->addError($attribute, '用户名或密码不正确.');}}}

我为上面看到的同一个字段设置了 2 条规则:

[['username'], 'number', 'message'=>'{attribute} 必须是数字'],[['用户名'], '字符串', '长度' =>8],

我希望表单针对以下 3 个情况显示不同的错误消息:

  1. 提供的值既不是数字,也不是 8 个字符(数字).
  2. 提供的值是一个数字,但不是 8 个字符(数字).
  3. 提供的值不是数字,而是 8 个字符(数字).

我的问题是 2 折:

A.有没有办法以任何标准,Yii2 方式组合这些规则.
B. 在我之前的问题中,我尝试设置自定义验证器(解决此问题的显而易见的方法),但它很简单地被忽略了.我可以使其验证的唯一方法是将 username 字段添加到场景中.但是,一旦我也添加了 password,它又被忽略了.你能想到的任何原因吗? situations:

  1. The provided value is neither a number, nor 8 characters (digits).
  2. The provided value is a number, but is not of 8 characters (digits).
  3. The provided value is not a number, but is of 8 characters (digits).

My question is 2 fold:

A. Is there a way to combine these rules in any standard, Yii2 way.
B. In my previous question I have tried to set up a custom validator (the obvious way to solve this), but it was very simply ignored. The only way I could make it validate was if I added the username field to a scenario. However, once I added password too, it was again ignored. Any reason's for this that you can think of? EDIT: skipOnError = false changed nothing at all in this behaviour.

So please, when you answer, make sure you test it preferably in yii2/advanced; I barely touched the default set up, so it should be easy to test.

EDIT: for clarity, I would like to only allow numbers that are of 8 characters (digits), so they can potentially have a leading 0, eg. 00000001, or 00000000 for that matter. This is why it has to be a numeric string.

解决方案

The best way to combine rules and display custom error messages for different situations is to create a custom validator. Now if you want that to work on client-side too (it was one of my problems detailed in question B above, thanks to @Beowulfenator for the lead on this), you have to create an actual custom validator class extended from the yii2 native validator class.

Here is an example:

CustomValidator.php

<?php

namespace app\components\validators;

use Yii;
use yii\validators\Validator;

class CustomValidator extends Validator
{
    public function init() {
        parent::init();
    }

    public function validateAttribute($model, $attribute) {
        $model->addError($attribute, $attribute.' message');
    }

    public function clientValidateAttribute($model, $attribute, $view)
    {
return <<<JS
messages.push('$attribute message');
JS;
    }
}

LoginForm.php

<?php
namespace common\models;

use Yii;
use yii\base\Model;
use app\components\validators\CustomValidator;

/**
 * Login form
 */
class LoginForm extends Model
{
    public $username;
    public $password;
    public $custom;

    private $_user;


    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            // username and password are both required
            [['username', 'password'], 'required'],
            // username should be a number and of 8 digits
            [['username'], 'number', 'message'=>'{attribute} must be a number'],
            [['username'], 'string', 'length' => 8],
            // password is validated by validatePassword()
            ['password', 'validatePassword'],
            ['custom', CustomValidator::className()],
        ];
    }

    // ...

login.php

<?php

/* @var $this yii\web\View */
/* @var $form yii\bootstrap\ActiveForm */
/* @var $model \common\models\LoginForm */

use yii\helpers\Html;
use yii\bootstrap\ActiveForm;

$this->title = 'Login';
?>
<div class="site-login text-center">
    <h1><?php echo Yii::$app->name; ?></h1>

    <?php $form = ActiveForm::begin([
        'id' => 'login-form',
        'fieldConfig' => ['template' => "{label}\n{input}"],
        'enableClientValidation' => true,
        'validateOnSubmit' => true,
    ]); ?>

    <?= $form->errorSummary($model, ['header'=>'']) ?>

    <div class="row">
        <div class="col-lg-4 col-lg-offset-4">
            <div class="col-lg-10 col-lg-offset-1">

                    <div style="margin-top:40px">
                        <?= $form->field($model, 'username') ?>
                    </div>

                    <div>
                        <?= $form->field($model, 'password')->passwordInput() ?>
                    </div>

                    <div>
                        <?= $form->field($model, 'custom') ?>
                    </div>

                    <div class="form-group" style="margin-top:40px">
                        <?= Html::submitButton('Login', ['class' => 'btn btn-default', 'name' => 'login-button']) ?>
                    </div>

            </div>
        </div>
    </div>

    <?php ActiveForm::end(); ?>

</div>

这篇关于Yii2:ActiveForm:在一个字段上组合规则/多重验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-19 11:37
查看更多