Skip to content

Instantly share code, notes, and snippets.

@alganet
Last active March 19, 2018 11:55
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alganet/b66bc8281672ca3d3b42 to your computer and use it in GitHub Desktop.
Save alganet/b66bc8281672ca3d3b42 to your computer and use it in GitHub Desktop.
Non-Fluent Respect\Validation

Non-Fluent Respect\Validation

Hi! I'm one of the developers of Respect\Validation and other less known Respect components. Feel free to ask any questions here or on reddit.

There are many micro-frameworks that rely on magic methods. We don't. In this article I'm gonna explore the Respect\Validation API without fluent interfaces or magic methods. I'll use a traditional dependency injection approach.

The following validator was inspired by one of our README examples:

use Respect\Validation\Validator as v;
$usernameValidator = v::alnum()->noWhitespace()->length(1,15);
$usernameValidator->validate('alganet'); //true

If you var_dump($usernameValidator), you'll see a composite of objects with Respect\Validation\Rules\Alnum, Respect\Validation\Rules\NoWhitespace and Respect\Validation\Rules\Length. There is a specific object for each rule, and the chain only builds the structure. You can build it by yourself:

use Respect\Validation\Rules;

$usernameValidator = new Rules\AllOf(
    new Rules\Alnum(),
    new Rules\NoWhitespace(),
    new Rules\Length(1, 15)
);
$usernameValidator->validate('alganet'); //true

This is still a very lean API. You can use it in any dependency injection container or test it in the way you want. Nesting is still possible:

use Respect\Validation\Rules;

$usernameValidator = new Rules\AllOf(
    new Rules\Alnum(),
    new Rules\NoWhitespace(),
    new Rules\Length(1, 15)
);
$userValidator = new Rules\Key('name', $usernameValidator);
$userValidator->validate(['name' => 'alganet']); //true

How It Works?

The Respect\Validation chain is an internal DSL. It acts in the creational realm of objects (where Abstract Factories and Builders live), and it's only job is to make rule construction terse and fluent.

FAQ

Is v in v::something a class name?

No! The class is Respect\Validation\Validator, we suggest v as a very short alias.

Is v::something() a static call?

Yes. Just like the default DateTime:createFromFormat() or Doctrine\ORM\Tools\Setup::createAnnotationMetadataConfiguration(). It builds something complex and returns for you.

I really don't like static calls, can I avoid it?

Yes. Just use $myV = new v; each time you want a new validator, and continue from there.

Do you have a static method for each rule?

No. We use __callStatic.

Magic methods are slow! Why do you use them?

They're optional. If you use the new interface, they won't be called.

(still, do some benchmarks, you'd be surprised with our implementation).

Why no documentation on this?

It is ongoing. I didn't thought people would prefer to use the raw API.

@harikt
Copy link

harikt commented Jan 12, 2015

Interesting. Didn't know this :-) . Thank you for the write up.

@designermonkey
Copy link

Hi @alganet

Could this style be written into the Feature Guide documentation alongside the DSL style please? There is functionality described in there that isn't here, for example: optional.

I think it would be of great benefit to users of this style to see how easy it really is.

Also, a year late after asking about it, thanks for this writeup.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment