3
\$\begingroup\$

We're trying to design validation classes with a common interface. This would apply to all validators. We would define a validator interface with a validate($input):bool method. Each validator would represent a specific data type (email address, login, etc.); the validate method would implement the appropriate logic.

Option 1: Instantiate a validator object (either directly or through a factory) to perform validation

class EmailValidator implements ValidatorInterface
{
    public function validate($input) { ... }
}

// Usage:
$var = new EmailValidator();
if ($var->validate($val)) { ... }

Option 2: Validator interface defines a static validate() method implemented by each validator

class EmailValidator implements ValidatorInterface
{
    public static function validate($input) { ... }
}

// Usage:
if (EmailValidator::validate($val)) { ... }

Which would be the best option to use? Are there better ways to go about this than those laid out above?

\$\endgroup\$

3 Answers 3

6
\$\begingroup\$

Don't use static methods. Eventually you will want to be able to apply a group of validators in a single operation i.e. testing for NonBlank then testing for Email. Easy to do with objects, far more challenging with statics.

It's interesting that your Validator is very similar to that used by the popular Symfony\Validator component. So I think it's safe to say you are on the right track.

Might want to take a look at the component just to get some ideas:

https://github.com/symfony/Validator

http://symfony.com/doc/current/book/validation.html

=================================================================

I don't understand why it would be more challenging with statics.

If you needed multiple constraints then creating instances, storing them in an array and then looping over the array is easier then using statics.

But lets consider a different problem. Suppose you want a UniqueEmailValidator which needs access to the database. It's a bit awkward using statics but:

$validator = new UniqueEmailValidator($db);  // Works well

And once you start using a dependency injection container you can do:

$validator = $container->getService('unique_email_validator');

Which hides the $db portion.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ I don't understand why it would be more challenging with statics. Since Vedran Sego says the same I guess you are on to something. \$\endgroup\$ Commented Aug 28, 2013 at 1:23
  • \$\begingroup\$ Thank you for elaborating. I was considering making them static for any simple validation, but instantiated for anything more complex (like the unique email validator). I suppose in the name of consistency they should all be instantiated, though. \$\endgroup\$ Commented Aug 28, 2013 at 13:26
0
\$\begingroup\$

I am not that familiar with static methods in PHP specifically, so my answer is a bit limited in the aspect of what can be done in PHP.

If possible in PHP, I'd say make both ways available.

Obviously, the appeal of the static method is in its ease of use. However, such approach also has its limitations.

For example, let's say you want to make a validator that would check if a validated value is in a certain list. With the static approach, you'd need to make a separate class for each list. But, if you make your class so that you instantiate it, you can make a general validator which would have list management methods (i.e., assignArray, addItem, clearItems, etc), and you could use that one single validator class for all the lists you want.

So, if PHP doesn't allow duality, I'd vote for the non-static approach.

\$\endgroup\$
0
\$\begingroup\$

Why not build a complete validator class that does multiple kind of form validation rather than using validation interface and inheriting from it Something like

<?php
    class Validator{
      //properties
      //functions
    }
 ?>

I feel all your method should be static since it aid flexibility.

\$\endgroup\$
1
  • \$\begingroup\$ This is more a comment than an answer. \$\endgroup\$ Commented Sep 6, 2018 at 5:29

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.