Pre-processing

Before you can use a custom validation rule, you must define the namespace prefix for the custom validation rule

ValidateConfig::instance()->setRulesPath('W7\\App\\Model\\Validate\\Rules\\');
1

It is recommended to define the validate-related settings in Provider.

Using rule objects

There are many useful validation rules within the validator; custom rules are also supported。 One way to register a custom validation rule is to create a new rule and inherit from W7\Validate\Support\Rule\BaseRule. The new rule is stored in the directory you have set up.

Once the rule is created, we can define its behavior. The passes method takes the attribute value and name and returns true or false depending on whether the attribute value matches the rule. The message attribute is the validation error message used in case of validation failure, which can be overridden by the message defined in the validator.

namespace W7\App\Model\Validate\Rules;

class Chs extends BaseRule
{
    /**
     * Default error message
     * @var string
     */
    protected $message = 'The value of :attribute can only have Chinese';
    
    /**
     * Determine if the validation rules pass。
     *
     * @param mixed $attribute
     * @param mixed $value
     * @return bool
     */
    public function passes($attribute, $value): bool
    {
        return is_scalar($value) && 1 === preg_match('/^[\x{4e00}-\x{9fa5}]+$/u', (string)$value);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

Once the rule object has been defined, you can pass an instance of the rule object to the validator by passing it along with other validation rules:

protected $rule = [
    'title' => 'required|chs',
];
1
2
3

The first letter of the custom extension rule can be lowercase, it is also recommended to use lowercase.

The rules also support standalone calls to use

Chs::make()->check("name");
1

Validation returns true, failure returns false

Custom rule incoming parameters

Custom rules, like other rules, also support passing in parameters, similar to max:100, in:0,1,2, which will be passed into the constructor of the custom rule class in order. as follows:

class Length extends BaseRule
{
    protected $message = 'The length of :attribute does not meet the requirement';

    protected $size;

    public function __construct(int $size)
    {
        $this->size = $size;
    }

    public function passes($attribute, $value): bool
    {
        return strlen($value) === $this->size;
    }
}







 










1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

Formatting error messages

In the appeal code, the error message may not be so clear. It may be better to put the $size variable into the error message, and we provide the $messageParam parameter to support formatting the error message, as follows:

class Length extends BaseRule
{
    protected $message = 'The length of :attribute should be %d bytes';

    protected $size;

    public function __construct(int $size)
    {
        $this->size         = $size;
        $this->messageParam = [$size];
    }

    public function passes($attribute, $value): bool
    {
        return strlen($value) === $this->size;
    }
}










 








1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

$messageParam is an array type, so the value passed in must be an array, such as using the rule length:10, then the message after the trigger is: The length of :attribute should be 10 bytes

$message Field Definition:

Formatting FormatDescription
%%Returns a percent sign %
%bBinary numbers
%cASCII value corresponding to the character
%dDecimal numbers containing positive and negative signs (negative, 0, positive)
%eUse lowercase scientific notation (e.g. 1.2e+2)
%EUse uppercase scientific notation (e.g. 1.2E+2)
%uDecimal numbers without positive or negative signs (greater than or equal to 0)
%fFloating point (local setting)
%FFloating point (non-local setting)
%gShorter %E and %f
%GShorter %E and %f
%oOctal numbers
%sString
%xHexadecimal numbers (lowercase letters)
%XHexadecimal numbers (uppercase letters)

Additional formatting values. Must be placed between % and a letter (e.g. %.2f).

  • \+ (Precede a number with + or - to define the positive or negative nature of the number. By default, only negative numbers are marked, and positive numbers are not marked.)
  • ' (Specifies what to use as padding, the default is spaces. It must be used in conjunction with the width specifier. Example: %'x20s (uses "x" as padding))
  • \- (Left Adjusted Variable Value)
  • [0-9] (Specify the minimum width of the variable value)
  • .[0-9] (Specify the number of decimal places or the maximum string length)

Note

If more than one of the above format values is used, the parameters of $messageParam must be used in the above order, and must not be out of order.

For more support on error messages please see Custom Error Messages

Using extensions

extend

Another way to register a custom validation rule is to use the extend method in Validate. Let's use this method in the validate to register a custom validation rule.

public function __construct()
{
    self::extend("check_admin",function($attribute, $value, $parameters, $validator){
        return $value === "owner";
    });
}
1
2
3
4
5
6

The custom validation closure takes four parameters: the name of the attribute to be validated $attribute, the value of the attribute $value, an array of parameters to be passed into the validation rule $parameters, and a Validator instance.

In addition to using closures, you can also pass in classes and methods to the extend method:

Validate::extend("check_admin","permissionValidate@checkAdmin");
1

Note

If your method is a static method, you can also pass in an array of [full class name, method name], if the method name is not passed, the default method name is validate.

Using class methods

Custom rules also support the direct use of methods under the current validator class, the rule is rule + rule name, e.g. ruleCheckLogin

Note

The checkLogin here and other methods registered under the current validator must not duplicate the rule name, otherwise it will overwrite

The Custom Rule Method class method takes four parameters: The name of the attribute to be validated $attribute, the value of the attribute $value, an array of parameters to be passed into the validation rule $parameters, and a Validator instance.

class LoginValidate extends Validate
{
    protected $rule = [
        'user' => 'required|alphaNum|checkLogin'
    ];

    protected $message = [
        'user.checkLogin' => 'Login failure'
    ];

    public function ruleCheckLogin($attribute, $value, $parameters, $validator): bool
    {
        return 'admin' === $value;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

replacer

If you need to define an error message, you can fill in the third parameter of extend, or define it via the replacer method

The replacer method accepts two parameters ruleName and a closure parameter, and the closure accepts four parameters: error message $message, the name of the attribute being validated $attribute, the name of the current rule $rule, an array of parameters to be passed into the validation rule $parameters

Validate::replacer("check_admin",function($message,$attribute,$rule,$parameters){
  return "Customized error messages"
});
1
2
3

In addition to using closures, passing in classes and methods to the replacer method is also supported

Validate::replacer("check_admin","permissionValidate@checkAdminMessage");
1

Note

Passing in classes and methods requires specifying the method as a public type, if it's a class, you need to pass in the full namespace, does not support array passing, such as the method name is not passed, the default method name replace.

Custom messages that can override default rules. To define error messages for custom methods, be sure to define the error rule extend first, then the error message replacer.

Use in the same way as with rule objects

protected $rule = [
    'title' => 'required|chs|check_admin',
];
1
2
3

extendImplicit

By default, when an attribute being validated is not present or contains an empty string, normal validation rules, including custom extensions, are not run. For example, the unique rule will not be run against an empty string:

$rules = ['name' => 'unique:users,name'];

$input = ['name' => ''];

// Validate passed
1
2
3
4
5

For a rule to run even when an attribute is empty, the rule must imply that the attribute is required. To create such an "implicit" extension, use the extendImplicit() method in Validate:

Validate::extendImplicit('foo', function ($attribute, $value, $parameters, $validator) {
    return $value == 'foo';
});
1
2
3

An "implicit" extension only implies that the attribute is required. Whether it actually invalidates a missing or empty attribute is up to you.

ImplicitRule

If you would like a rule object to run when an attribute is empty, you should implement the Illuminate\Contracts\Validation\ImplicitRule interface. This interface serves as a "marker interface" for the validator; therefore, it does not contain any methods you need to implement.

extendDependent

If we want to define a custom extension to validate the array, we will find that neither extend nor extendImplicit will resolve *, so we need to use the extendDependent method in Validate:

Validate::extendDependent('contains', function ($attribute, $value, $parameters, $validator) {
    // The $parameters passed from the validator below is ['*.provider'], when we imply that this
    // custom rule is dependent the validator tends to replace the asterisks with the current
    // indices as per the original attribute we're validating, so *.provider will be replaced
    // with 0.provider, now we can use array_get() to get the value of the other field.
    
    // So this custom rule validates that the attribute value contains the value of the other given attribute
    return str_contains($value,Arr::get($validator->getData(),$parameters[0]));
});

$v = new Validate($request);
$v->setRules([
    '*.email' => 'contains:*.provider'
])->check([
    [
        'email' => '995645888@qq.com', 'provider' => 'qq.com'
    ]
]);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

Regular Expression Rule

Supports direct use of regular validation, e.g:

'id' => 'regex:/^\d+$/',
1

If your regular expression contains the | symbol, it must be defined in an array.

'id' => ['regex:/^\d+$/']
1

You can also implement a predefined regular expression and call it directly, for example, by defining the regex property in the validator class and then using regex: + regular name in the rule

class Test extends \W7\Validate\Validate
{
    protected $regex = [
        'number' => '/^\d+$/'
    ];

    protected $rule = [
        'id' => 'regex:number'
    ];
}



 



 


1
2
3
4
5
6
7
8
9
10
Last Updated: 10/13/2021, 2:39:38 PM