Skip to content

foodkit/pasvl

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

54 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Latest Stable Version Build Status Total Downloads License

PASVL - PHP Array Structure Validation Library

The purpose of this library is to validate an existing (nested) array against a template and report a mismatch. It has the object-oriented extendable architecture to write and add custom validators.

Highly inspired by abandoned package ptrofimov/matchmaker. While the mentioned package was written in a functional way, current one embraces OO architecture in a sake of readability, maintainability, and extendability.

Installation

composer require lezhnev74/pasvl

Examples

Refer to files in Examples folder.

Example 1. Data does not match the pattern

// import fully qualified class names to your namespace
use PASVL\Traverser\VO\Traverser;
use PASVL\ValidatorLocator\ValidatorLocator;

$data = ["password"=>"weak"];
$pattern = ["password" => ":string :min(6)"];

$traverser = new Traverser(new ValidatorLocator());
$result = $traverser->check($pattern, $data); // returns false 

Example 2. Data matches the pattern

// import fully qualified class names to your namespace
use PASVL\Traverser\VO\Traverser;
use PASVL\ValidatorLocator\ValidatorLocator;


$data = [
   [
       'type' => 'book',
       'title' => 'Geography book',
       'chapters' => [
           'eu' => ['title' => 'Europe', 'interesting' => true],
           'as' => ['title' => 'America', 'interesting' => false],
       ],
   ],
   [
       'type' => 'book',
       'title' => 'Foreign languages book',
       'chapters' => [
           'de' => ['title' => 'Deutsch'],
       ],
   ],
];

$pattern = [
    '*' => [
        'type' => 'book',
        'title' => ':string :contains(book)',
        'chapters' => [
            ':string :length(2) {1,3}' => [
                'title' => ':string',
                'interesting?' => ':bool',
            ],
        ],
    ],
];

$traverser = new Traverser(new ValidatorLocator());
$result = $traverser->check($pattern, $data); // returns true

Pattern

An array consists of keys and values. A pattern can set expectations for both.

A pattern consists of a 3 parts:

  • main validator: :string
  • optional sub-validators: :min(2) :max(4)
  • quantifier (for keys only): {1,2}

Example: :string :min(1) :max(4) {1,2}.

Pattern definition

A pattern can be set in a few ways:

  • as an explicit key name:
    $pattern = ["name"=>"Nico"]
  • as an explicit optional key name:
    // array can have optional key "name"
    $pattern = ["name?"=>"Nico"]
  • as validators list:
    //array can have any number of string keys of exactly 4 bytes long
    // here "string" - main validator, "len" - sub-validator
    $pattern = [":string :len(4)"=>"Nico"]
    In this case no other symbols are allowed except validator names and arguments. Invalid pattern: :string name.
  • as validators list with quantifier:
    //array can have any count (zero or more) string keys matching given regexp (frist_name or last_name)
    //please note, that closing parenthesises within regex MUST be escaped in order to work correctly: 
    $pattern = [":string :regexp(#(first|last\)_name#) *"=>":string"]

Quantifier definition

A quantifier set expectations on keys. If none is set then default is assumed - !.

Available quantifiers:

  • ! - one key required (default)
  • ? - optional key
  • * - any count of keys
  • {2} - strict keys count
  • {2,4} - range of keys count

Validator definition

A validator is a class which has single __invoke($data) method and optional methods acting as sub-validators. A pattern can have a single main validator name and any number of sub-validators. Validator's definition must start with : and then the name follows.

Validators and sub-validators can have arguments: :between(1,10) (but empty brackets are not allowed). Validator and sub-validator names follow the same rules as any PHP label:

/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/

If given pattern does not match the above description, then it is used as an implicit value:

// This pattern matches only if data has key ": string"
$pattern = [
    ": string" => ":any"
];

Validator lookup

Built-in validator are found automatically. In case you want to use your own validator class, extend ValidatorLocator class and add your logic to locate validator classes. Refer to folder src/Validator.

Hints

  • PHP casts "1" to 1 for array keys:
    $data = ["12"=>""];
    $pattern_invalid = [":string"=>""];
    $pattern_valid = [":int"=>""];

🏆 Contributors

  • Greg Corrigan. Greg spotted a problem with nullable values reported as invalid.
  • Henry Combrinck. Henry tested the library extensively on real data and found tricky bugs and edge cases. Awesome contribution to make the package valuable to the community.
  • @Averor. Found a bug in parenthesis parsing.

License

This project is licensed under the terms of the MIT license.

TODO

  • Add validator classes
  • Add more real-world examples
  • Improve README

Packages

No packages published

Languages

  • PHP 100.0%