Pvalidate: Custom Validation Rule

We can create custom rule for validation for the PValidate package. Let’s see how to create and use a custom validation rule in the Pvalidate library for PHP.

This guide will provide a step-by-step example of implementing a custom password validation rule and integrating it into a PHP class.

We will create a custom password validation rule using PHP attributes. This rule will enforce the following criteria:

Minimum length
Must contain at least one uppercase letter
Must contain at least one digit
Must contain at least one special character from !@#$%^&*

Step #1: Define the Custom Validation Rule

Here is the custom validation rule class:

Create a class for the validation rule.
Declare your class as an attribute by adding #[Attribute] to the class. The #[Attribute] annotation makes the class usable as a PHP attribute.
Inherit from Webhkp\Pvalidate\Rules\ValidationRule.
You can define the constructor as per your requirement, there is no strict rule for this.
Define isValid() method, which returns a boolean value. Write logic to check if the value satisfies the requirement or not.
Define method getErrors() which returns an array of the error message(s). Provides detailed error messages if the validation fails.

NOTE

$value property is available as part the ValidationRule inheritance. So we can use $this->value anywhere in the custom rule class to get the value of the field.
We can access the field name using $this->name.
use Webhkp\Pvalidate\Rules\ValidationRule;


#[Attribute]
class MyCustomPasswordRule extends ValidationRule {
    public function __construct(private readonly string $minLength) {
    }

    public function isValid(): bool {
        if (strlen($this->value) < $this->minLength) {
            return false;
        }

        // Must contain one Upper case letter
        if (!preg_match('/[A-Z]/', $this->value)) {
            return false;
        }

        // Must contain a digit
        if (!preg_match('/[0-9]/', $this->value)) {
            return false;
        }

        // Must contain a special character
        if (!preg_match('/[!@#$%^&*]/', $this->value)) {
            return false;
        }

        return true;
    }

    public function getErrors(): array {
        $errors = [];

        if (!$this->isValid()) {
            $errors['password'] = $this->name . ' is not a valid password (minimum length '
                . $this->minLength . ', must contain an uppercase letter, '
                . 'a digit and a special character from "!@#$%^&*")';
        }

        return $errors;
    }
}

Step #2: Integrate the Custom Rule into a Class

Next, we will integrate the custom password rule into a PHP class. This class will use the custom rule to validate the password property.

The MyClass class uses the MyCustomPasswordRule attribute to enforce the custom password rule on the password property.

class MyClass {
    public function __construct(
        #[Required]
        public string $name
    ) {
    }

    #[MyCustomPasswordRule(6)]
    public string $password = 'mysimplepass';
}

Step #3: Validate an Instance of the Class

Create an instance of MyClass and set the required properties.
Use Validator::validate to validate the instance.
Check the validation response to see if the object is valid and retrieve any error messages.
$myObj = new MyClass("Test ABC");

// Validate the object
$validationResponse = Validator::validate($myObj);

var_dump($validationResponse->isValid());
var_dump($validationResponse->getErrors());

Full Code Example

Here is the full code described above-

<?php

require_once "vendor/autoload.php";

use Webhkp\Pvalidate\Rules\Custom;
use Webhkp\Pvalidate\Rules\Regex;
use Webhkp\Pvalidate\Rules\ValidationRule;
use Webhkp\Pvalidate\Validator;
use Webhkp\Pvalidate\Rules\Required;
use Webhkp\Pvalidate\Rules\Range;
use Webhkp\Pvalidate\Rules\Allow;
use Webhkp\Pvalidate\Rules\Disallow;

#[Attribute]
class MyCustomPasswordRule extends ValidationRule {
    public function __construct(private readonly string $minLength) {

    }

    public function isValid(): bool {
        if (strlen($this->value) >= $this->minLength) {
            return false;
        }

        // Must contain one Upper case letter
        if (!preg_match('/[A-Z]/', $this->value)) {
            return false;
        }

        // Must contain a digit
        if (!preg_match('/[0-9]/', $this->value)) {
            return false;
        }

        // Must contain a special character
        if (!preg_match('/[!@#$%^&*]$/', $this->value)) {
            return false;
        }

        return true;
    }

    public function getErrors(): array {
        $errors = [];

        if (!$this->isValid()) {
            $errors['password'] = $this->name . ' is not a valid password (minimum length '
                . $this->minLength . ', must contain a uppercase letter, '
                . 'a digit and a special character from "!@#$%^&*")';
        }

        return $errors;
    }

}

class MyClass {
    public function __construct(
        #[Required]
        public string $name
    ) {

    }

    #[MyCustomPasswordRule(6)]
    public string $password = 'mysimplepass';
}


// Create object
$myObj = new MyClass("Test ABC");

// Validate the object
$validationResponse = Validator::validate($myObj);

var_dump($validationResponse->isValid());
var_dump($validationResponse->getErrors());

Output:

bool(false)


array(1) {
  ["password"]=>
  array(3) {
    ["value"]=>
    string(12) "mysimplepass"
    ["valid"]=>
    bool(false)
    ["errors"]=>
    array(1) {
      ["password"]=>
      string(133) "password is not a valid password (minimum length 6, must contain a uppercase letter, a digit and a special character from "!@#$%^&*")"
    }
  }
}

Directly use MyCustomPasswordRule

We can also use the custom rule directly, to parse and validate a value. Here is an example-

// Check password validation
$passwordRule = new MyCustomPasswordRule(10);
$passValidationResult = $passwordRule->parse('simplepass');

var_dump($passValidationResult->isValid());
var_dump($passValidationResult->getErrors());

Output:

bool(false)

array(1) {
  ["password"]=>
  string(126) " is not a valid password (minimum length 10, must contain a uppercase letter, a digit and a special character from "!@#$%^&*")"
}

Leave a Comment


The reCAPTCHA verification period has expired. Please reload the page.