Home arrow PHP arrow Page 2 - Validating URLs with the Strategy Design Pattern

Review: the source classes defined so far - PHP

In this penultimate part of the series, I will build a strategy class that validates URLs using the built-in PHP function “filter_var().” This process is similar to defining other strategy classes discussed in previous parts, so you shouldn’t have major difficulties understanding its underlying logic.

TABLE OF CONTENTS:
  1. Validating URLs with the Strategy Design Pattern
  2. Review: the source classes defined so far
  3. Validating URLs with the Strategy design pattern
  4. Testing the UrlValidator class
By: Alejandro Gervasio
Rating: starstarstarstarstar / 2
April 27, 2010

print this article
SEARCH DEV SHED

TOOLS YOU CAN USE

advertisement

As usual, before I start building the additional strategy class mentioned in the introduction, which as you know will be charged with validating URLs, I'm going to spend a few moments showing the source code of all the sample classes developed so far. This way you can quickly recall the role played by each of them in the implementation of the strategy pattern within a "real" web application.

With that being said, here's the first of these classes. It's a basic form helper that takes a group of validator objects through its "addValidator()" method. These objects are used for checking the validity of a given set of data:

(FormHelper.php)

<?php

class FormHelper

{

    protected $_validators = array();

    protected $_errors = array();

   

    // add a validator

    public function addValidator(AbstractValidator $validator)

    {

        $this->_validators[] = $validator;

        return $this;

    }

   

    // get all the validators

    public function getValidators()

    {

        return !empty($this->_validators) ? $this->_validators : null;

    }

     

    // validate inputted data

    public function validate()

    {

        $validators = $this->getValidators();

        if (null !== $validators)

        {

            foreach ($validators as $validator)

            {

                if (!$validator->validate())

                {

                    $this->_errors[] = $validator->getFormattedError();

                }

            } 

        }

        return empty($this->_errors) ? true : false;

    }

   

    // get validation errors as an array

    public function getErrors()

    {

        return $this->_errors;

    }

   

    // get validation errors as a string

    public function getErrorString()

    {

        $errors = $this->getErrors();

        return !empty($errors) ? implode('', $errors) : '';

    }

   

    // clear state of the form helper

    public function clear()

    {

        $this->_validators = array();

        $this->_errors = array();

    }  

}

As you can see, the "FormHelper" class is a simple container that permits you to store different validation objects in an internal array, which is used afterward by the "validate()" method to determine whether or not a supplied value is valid.

Since the logic that drives this form helper has been discussed in past articles of the series, I suggest that you move on and take a look at the following abstract class. It defines the generic structure and metadata of the validator objects just mentioned:  

(AbstractValidator.php)

<?php

abstract class AbstractValidator

{

    protected $_value = '';

    protected $_filter = '';

    protected $_options = null;

    protected $_errorMessage = '';

    protected $_errorPrefix = '<p>';

    protected $_errorSufix = '</p>';

   

    // constructor

    public function __construct($value, array $options = null)

    {

        $this->_value = $value;

        if (null !== $options)

        {

           $this->setOptions($options);

        }

    }

   

    // get supplied value

    public function getValue()

    {

        return $this->_value;

    }

   

    // set validation options

    public function setOptions(array $options)

    {

        if (empty($options))

        {

            throw new ValidatorException('Invalid options for the validator.');

        }

        $this->_options = $options;

    }

   

    // get validation options

    public function getOptions()

    {

        return $this->_options;

    }

     

    // set the validation filter

    public function setFilter($filter)

    {

        if (!is_string($filter))

        {

            throw new ValidatorException('Invalid filter for the validator.'); 

        }

        $this->_filter = $filter;

    }

   

    // get the validation filter

    public function getFilter()

    {

        return $this->_filter;

    }

   

    // set the error message

    public function setErrorMessage($errorMessage)

    {

        if (!is_string($errorMessage))

        {

            throw new ValidatorException('Invalid error message for the validator.');    

        }

        $this->_errorMessage = $errorMessage;

    }

   

    // get error message

    public function getErrorMessage()

    {

        return $this->_errorMessage;

    }

             

    // get formatted error string

    public function getFormattedError()

    {

        return $this->_errorPrefix . 'The value ' . $this->getValue() . ' is incorrect. ' . $this->getErrorMessage() . $this->_errorSufix;

    }

   

    // validate the supplied value 

    public function validate()

    {

        return filter_var($this->getValue(), $this->getFilter(), $this->getOptions());  

    }

}

(ValidatorException.php)

<?php

class ValidatorException extends Exception{}

Well, if I had to say something relevant about the above "AbstractValidator" class, it would be that the driving force of its "validate()" method is the "filter_var()" PHP function. Obviously, this method, along with the corresponding getters and mutators (nice word, right?) allow you to define the logic and structure of a generic validation component, which must be refined by the pertinent subclasses.

And speaking of refined implementations, below is the list of concrete subclasses derived from the base "AbstractValidator" class. They come in useful for checking integers, float numbers and email addresses:

(IntegerValidator.php)

<?php

class IntegerValidator extends AbstractValidator

{

    protected $_filter = FILTER_VALIDATE_INT;

    protected $_errorMessage = 'Please enter an integer value.';

}

(FloatValidator.php)

<?php

class FloatValidator extends AbstractValidator

{

    protected $_filter = FILTER_VALIDATE_FLOAT; 

    protected $_errorMessage = 'Please enter a float value.';

}

(EmailValidator.php)

<?php

class EmailValidator extends AbstractValidator

{

    protected $_filter = FILTER_VALIDATE_EMAIL; 

    protected $_errorMessage = 'Please enter a valid email address.';

}

From the previous code samples, it's clear to see how easy it is to create a concrete subclass that permits you to check a specified type of data. In all cases, defining a specific validation component is reduced to overriding the "$_filter" and "$_errorMessage" properties declared by the parent "AbstractValidator" and nothing else.

All right, at this point I've shown you all of the strategy classes developed so far, which are more than enough for building a fully-functional validation web application. As I expressed in the introduction, however, it'd be useful to create yet another class that allows us to determine if a supplied value is a valid URL. Doing this is so simple, that experience is really worthwhile.

In keeping with this, in the following segment I'm going to create a final strategy class to check URLs, whose definition will look very similar to the ones that you saw before.

Now, go ahead and read the next section. It's only one click away.



 
 
>>> 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: