paint-brush
Object Validator for PHP 8by@skillstacker
1,861 reads
1,861 reads

Object Validator for PHP 8

by Ivan GrigorovJuly 14th, 2022
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

This is simple attribute validation for PHP Models, based on the new features, presented in PHP 8. It works as a standalone and can be used in custom projects or in libraries like Symfony and Laravel.

Company Mentioned

Mention Thumbnail
featured image - Object Validator for PHP 8
Ivan Grigorov HackerNoon profile picture


Have you ever tried to validate an object in PHP. Maybe you use Models, ViewModels or RequestModels. Maybe you hate writing if-else, loops and swiches to check your values. Maybe you do not like to use different validators for every framework.


At least I do.


So I present to you my general solution using the strengths of PHP 8. Clean, concise, and easy.


What this does is use the new PHP attributes to validate your value objects. (Especially if you are using DDD) or/and you do not want this to depend on a specific framework.


It consists of the following features:


  • Lots of validations
  • Supports also nested object validation
  • Repeatable validation attributes
  • Works with private properties and methods
  • Works with constructor promotion
  • Memory and time profiling
  • Custom error messages
  • Custom property and method names for the exceptions
  • Severity levels
  • Debug explorer
  • Callback execution

Example

<?php

use RMValidator\Attributes\PropertyAttributes\Collection\UniqueAttribute;
use RMValidator\Attributes\PropertyAttributes\File\FileExtensionAttribute;
use RMValidator\Attributes\PropertyAttributes\File\FileSizeAttribute;
use RMValidator\Attributes\PropertyAttributes\Numbers\RangeAttribute;
use RMValidator\Attributes\PropertyAttributes\Object\NestedAttribute;
use RMValidator\Attributes\PropertyAttributes\Strings\StringContainsAttribute;
use RMValidator\Enums\ValidationOrderEnum;
use RMValidator\Options\OptionsModel;
use RMValidator\Validators\MasterValidator;

require __DIR__ . '/vendor/autoload.php';


class Test 
{
    public function __construct(
        #[RangeAttribute(from:10, to:50)]
        #[RangeAttribute(from:10, to:30)]
        public int $param)
    {

    }

    #[RangeAttribute(from:10, to:30)]
    const propTest = 40;

    #[UniqueAttribute()]
    public function custom() {
        return ['asd', 'asdk'];
    }

    #[FileSizeAttribute(fileSizeBiggest: 20, fileSizeLowest: 10)]
    #[FileExtensionAttribute(expected:['php'])]
    private function getFile() {
        return __FILE__;
    }

    #[FileSizeAttribute(fileSizeBiggest: 20, fileSizeLowest: 10)]
    #[FileExtensionAttribute(expected:['php'])]
    public string $file = __FILE__;

    #[StringContainsAttribute(needle:"asd")]
    public string $string = "23asd";

    #[RangeAttribute(from:10, to:30)]
    public int $prop = 40;
}

class UpperTest
{
    #[NestedAttribute(excludedProperties:['param'])]
    private Test $test;

    public function __construct(Test $test) {
        $this->test = $test;
    }
}

$test = new Test(40);

try {
    MasterValidator::validate(new UpperTest($test), 
    new OptionsModel(orderOfValidation: [ValidationOrderEnum::PROPERTIES, 
                                         ValidationOrderEnum::METHODS,
                                         ValidationOrderEnum::CONSTANTS], 
                     excludedMethods: ['getFile'], 
                     excludedProperties: ['file']));
} catch(Exception $e) {
    var_dump($e);
}


I am getting exited how this thing gets shape, but it still can be developed further and evolve. I will enjoy all sorts of feedback, recommendations and support. :)


It can be found in the link below.

https://github.com/IvanGrigorov/VMValidator


Also published here.