Home arrow PHP arrow PHP: Building Concrete Validators

PHP: Building Concrete Validators

In this two-part tutorial, I show why the use of static helper classes can be detrimental to building robust and scalable object-oriented applications in PHP (though you should take into account that the concept is language agnostic). I also implement a set of instantiable, fine-grained validators, which can be easily tested in isolation, injected into the internals of other objects, and so forth.

TABLE OF CONTENTS:
  1. PHP: Building Concrete Validators
  2. Validating Incoming Data: Putting the Validators To Work
By: Alejandro Gervasio
Rating: starstarstarstarstar / 0
December 21, 2011

print this article
SEARCH DEV SHED

TOOLS YOU CAN USE

advertisement

Constructing purely static helper classes can hurt you, especially when you're trying to build applications that adhere to the principles of good object-oriented programming. As I explained extensively in the first part of this tutorial, static helpers are inflexible structures that can only be extended via Inheritance, and that don’t exploit the benefits of Polymorphism or dependency injection.      

Naturally, the most educational way to learn why static helpers (or any other kind of static class, of course) should be replaced with instantiable classes is through some concrete, easy-to-follow examples. In keeping with this idea, in the aforementioned installment, I went through the implementation of a trivial static helper. It simply validated different types of incoming data, including integer and float numbers, URLs and email addresses too.

Due to the above reasons -- and a few others worth noting, like violating the Open/Closed and the Single Responsibility principles -- the helper was a pain to use, even in the environment of an example. Imagine what you would have to face in production! Fortunately, turning static helpers into instantiable structures is a snap.

Again, the best way to prove this concept is by example. Hence, I decided to take a more efficient approach and break down my “catch-all” sample helper into a set of discrete classes, with a more refined and limited scope of responsibilities. To be frank, so far I've managed to create a single interface implemented by these concrete classes and the abstract parent that they share. Obviously, the next step is to show how the classes look, so that you can see how turning them into non-static structures can yield a host of benefits.

Spawning a Batch of Concrete Validators in PHP

As I just stated in the introduction, it’s ridiculously simple to turn the previous static validator into a set of non-static ones, which can be easily extended, injected and so forth. To accomplish this, I first defined a segregated interface along with an abstract parent, which looked like this: 

(Library/Helper/ValidatorInterface.php)

<?php

namespace Library\Helper;

interface ValidatorInterface
{
    /**
     * Validate the given value
     */
    public function validate(); 
}     


(Library/Helper/AbstractValidator.php)

<?php

namespace Library\Helper;

abstract class AbstractValidator
{
    const DEFAULT_ERROR_MESAGE = 'The supplied value is invalid.';
    protected $_value;
    protected $_errorMessage = self::DEFAULT_ERROR_MESAGE;
   
    /**
     * Constructor
     */
    public function __construct($value = null, $errorMessage = null)
    {  
        if ($value !== null) {
            $this->setValue($value);
        }
        if ($errorMessage !== null) {
           $this->setErrorMessage($errorMessage);
        }
    }
   
    /**
     * Set the value to be validated
     */
    public function setValue($value)
    {
        $this->_value = $value;
    }
   
     /**
     * Get the inputted value
     */
    public function getValue()
    {
        return $this->_value;
    }
     
    /**
     * Set the error message
     */
    public function setErrorMessage($errorMessage)
    {
        if (!is_string($errorMessage) || empty($errorMessage)) {
            throw new \InvalidArgumentException('The error message is invalid. It must be a non-empty string.');
        }
        $this->_errorMessage = $errorMessage;
    }
   
    /**
     * Get the error message
     */
    public function getErrorMessage()
    {
        return $this->_errorMessage;
    }
   
    /**
     * Reset the error message to the default value
     */
    public function resetErrorMessage()
    {
        $this->_errorMessage = self::DEFAULT_ERROR_MESAGE;
    }       
}

Since the above abstract validator and the “ValidatorInterface” interface should be familiar to you, as they were discussed in detail in the preceding article, the next logical step is to create the batch of concrete validators just mentioned. If you’re wondering how they look, well, here they are:

(Library/Helper/EmailValidator.php)

<?php

namespace Library\Helper;

class EmailValidator extends AbstractValidator implements ValidatorInterface
{
    const DEFAULT_ERROR_MESAGE = 'The supplied email address is invalid.';
       
    /**
     * Validate an email address
     */
    public function validate()
    {
        return filter_var($this->_value, FILTER_VALIDATE_EMAIL);  
    }    
}


(Library/Helper/FloatValidator.php)

<?php

namespace Library\Helper;

class FloatValidator extends AbstractValidator implements ValidatorInterface
{
    const DEFAULT_ERROR_MESAGE = 'The supplied value is an invalid float number.';
   
    /**
     * Validate a float number
     */
    public function validate()
    {
        return filter_var($this->_value, FILTER_VALIDATE_FLOAT);  
    }    
}


(Library/Helper/IntegerValidator.php)

<?php

namespace Library\Helper;

class IntegerValidator extends AbstractValidator implements ValidatorInterface
{
    const DEFAULT_ERROR_MESAGE = 'The supplied value is an invalid integer number.';
   
    /**
     * Validate an integer number
     */
    public function validate()
    {
        return filter_var($this->_value, FILTER_VALIDATE_INT);  
    }    
}


(Library/Helper/UrlValidator.php)

<?php

namespace Library\Helper;

class UrlValidator extends AbstractValidator implements ValidatorInterface
{
    const DEFAULT_ERROR_MESAGE = 'The supplied URL is invalid.';
   
    /**
     * Validate a URL
     */
    public function validate()
    {
        return filter_var($this->_value, FILTER_VALIDATE_URL);  
    }    
}

While admittedly the implementation of this set of brand new validators is pretty standard and the process can be grasped quickly, you should focus your attention on the benefits achieved with this simple change. First of all, the classes can be instantiated, injected, tested, and easily passed around across the tiers of an application. And second, they perform well-differentiated tasks; each one is responsible for validating only one specific type of data. This is definitely, a big win for the Single Responsibility principle.

So far, so good. Now that you've grasped how the validators do their thing, it’s time to see how they can be put to work side by side in a concrete use case. This will be done in the following section.



 
 
>>> More PHP Articles          >>> More By Alejandro Gervasio
 

blog comments powered by Disqus
escort Bursa Bursa escort Antalya eskort
   

PHP ARTICLES

- Hackers Compromise PHP Sites to Launch Attac...
- Red Hat, Zend Form OpenShift PaaS Alliance
- PHP IDE News
- BCD, Zend Extend PHP Partnership
- PHP FAQ Highlight
- PHP Creator Didn't Set Out to Create a Langu...
- PHP Trends Revealed in Zend Study
- PHP: Best Methods for Running Scheduled Jobs
- PHP Array Functions: array_change_key_case
- PHP array_combine Function
- PHP array_chunk Function
- PHP Closures as View Helpers: Lazy-Loading F...
- Using PHP Closures as View Helpers
- PHP File and Operating System Program Execut...
- PHP: Effects of Wrapping Code in Class Const...

Developer Shed Affiliates

 


Dev Shed Tutorial Topics: