Build Your Own Validation Library
Around November last year, i worked on a very small personal project. It was a CRD app (the U is missing, should have been CRUD). You couldn’t update stuffs. Deleting, reading and creating were allowed. Immutability is a thing right. Probably the biggest thing this days.
The above mentioned project was written without a framework, not even libraries. It had just 6 routes -
No route like
/list/id.. Yup… You can’t even view a single item. You must view it all in one large chunk
I couldn’t use Aura Router for just this as much i love the library, Twig or any of the cool stuffs i usually reach out to while working on a framework-less project.
It turns out i was kidding myself. I was already about to pull in
respect/validation as a dependency. But i backed off, re-evaluated my needs. I was only going to make use of just two validation rules in the project - the email and the length rule. The next logical step was to write one myself.
Hold on Tiger!! There are thousands of validators on Packagist already. You should spend some minutes there to evaluate that which fits your project. Stucked because there’s tons of them available ? Just use
Our validator is going to be extremely simple. Extremely simple it’d fit in a single file. Concrete classes, No. Anonymous classes ? Yep. Huge library of rules ? Hell No .
To keep things simple, we would be making use of something kind of related to Laravel’s validation rule syntax . Below are some valid definitions :
Quick one. The word before the
:delimiter stands for the index of the value we are trying to validate - say
$_POST['password']. While every other thing after the
:delimiter denotes rules definition.
Back to Business
Enough of the talking. This is where we get to implement the validator.
Since this validator is quite small, we would be composing functions - 7 in total - together. 2 of this functions are just wrappers for anonymous classes. 2 are for the validation rules - length and email. Some other 2 acts as the validator engine while the last one throws an Exception
We would be creating a file in the
validator.php. Namespace would be
Reeval - like Re-evaluate user’s input.
The code for this has been put on Github.
If the above seems a little bit weird, you should get up to speed on anonymous classes by skimming through the docs
We have an anonymous class within the
validator method that helps us check if our checks was successfull or not via the
passes methods. The
errorBag function handles the addition of errors to the collection already available.
The next thing we have coming is the validator engine itself. This would be responsible for parsing the rule set passed to it and determining if our validator understands them. Else we throw an exception.
validate method should be fairly easy to grok, the most interesting part here is the
parseValidatorRules here. Our validator’s dialect can be one of the following :
another_mail:length=>4|50,email. So we first get the index - in this case
,(comma). Rules themselves can be delimited by the arrow operator,
=>. Then we return an array to make it much more readable and useable.
I like testing, so we are going to write some tests.
We are testing the
parseValidatorRules alone. This is to allow maximum assurance that “it works” with our parser before going to some other interesting things.
You would notice that the
validate function does call some other functions depending on the rule type. We haven’t written those, let’s have that fixed. There are two rules in total, but we are taking it one at a time.
The length rule
This is correct but my highlighting tool screws the coloring up
There are two valid usecases here - Minimum and maximum length - . The maximum length doesn’t have to be defined, say -
The Email rule
Done. Nah, we hafta write some more tests to see if they work. The code block below contain tests for both rules.
We haven’t covered an edge-case though. How about invalid rules ? The engine would throw an exception on encountering one right ?
With this, we have completed our validator and can sleep knowing fully well that it works - thanks to our test suite. But there are some issues with our validatior :
- Lack of rules. Solution => Use packagist
- Dependent on
$_POST. Cannot work outside
HTTP. Solution - You can update the
validatemethod to allow passing an array containing the values for validation.
PS - If you are into this type of validation rules, checkout this nifty library 
 There are libraries with tons of rules on packagist.
 Pipe delimited rule definitions are cool. But folks be complaining about IDE support and the likes though.
 My personal preference for throwing exceptions - most of the time - is to define it (the exception) in a standalone function/method. I think that’s called SRP.. Lol
 Contributed to this project sometime last year.