2010-07-15 5 views
6

im am fait une classe de validation php avec des sous classes qui l'étendent, par exemple, mobile, banlieue, credit_card, ectclasses php ... validation

donc, l'idée est que vous pouvez appeler

$validation = new Validation('mobile'); 
$valid = $validation->validate($number); 

$validation->type('suburb'); 
$valid2 = $validation->validate($suburb); 

maintenant mon idée pour ce faire est d'avoir

class Validation() { 
    private $v_type = null; 

    function __construct($type) { 
     $this->type($type); 
    } 

    public function type($type) { 
     $this->v_type = new $type(); 
    } 

    public function validate($info) { 
     return $this->v_type->validate($info); 
    } 
} 

comme un exemple très basique

mais y a-t-il une meilleure façon de le faire?

Répondre

9

Vous pourriez le faire de cette façon, mais cela pourrait être amélioré. Avoir la propre capsule de validateurs leur propre logique de validation est bonne. Les étendre à partir d'une classe de base n'est pas. Implémentons une interface à la place. De cette façon, n'importe quelle classe peut être un validateur.

interface IValidate 
{ 
    public function validate($value); 
} 

validateurs ressembleraient ce alors:

class IsNumeric implements IValidate 
{ 
    public function validate($value) 
    { 
     return is_numeric($value); 
    } 
} 

et

class GreaterThan implements IValidate 
{ 
    protected $_value; 
    public function __construct($value) 
    { 
     $this->_value = $value; 
    } 
    public function validate($value) 
    { 
     return $value > $this->_value; 
    } 
} 

Vous auriez encore une classe principale Validator. Contrairement à votre exemple, le validateur ci-dessous accepte plusieurs validateurs, ce qui vous permettra de créer une chaîne de filtres.

class Validator implements IValidate 
{ 
    protected $_validators; 

    public function addValidator(IValidate $validator) 
    { 
     $this->_validators[] = $validator; 
     return $this; 
    } 
    public function validate($value) 
    { 
     foreach($this->_validators as $validator) { 
      if ($validator->validate($value) === FALSE) { 
       return FALSE; 
      } 
     } 
     return TRUE; 
    } 
} 

Et cela pourrait être utilisé comme:

$validator = new Validator; 
$validator->addValidator(new IsNumeric) 
      ->addValidator(new GreaterThan(5)); 

var_dump($validator->validate('ten')); // FALSE 
var_dump($validator->validate('10')); // TRUE 
var_dump($validator->validate('1')); // FALSE 

Ce qui précède est à peu près un Command pattern. Et en raison du Validator implémentant IValidate, c'est aussi un Composite. Vous pouvez prendre la chaîne Validator ci-dessus et l'empiler dans une autre chaîne de validateurs, par ex.

$numericGreaterThanFive = new Validator; 
$numericGreaterThanFive->addValidator(new IsNumeric) 
         ->addValidator(new GreaterThan(5)); 

$otherValidator = new Validator; 
$otherValidator->addValidator(new Foo) 
       ->addValidator(new Bar) 
       ->addValidator($numericGreatherThanFive); 

Pour plus de commodité, vous pouvez ajouter une méthode de fabrication statique pour créer validateurs avec les objets réels de validation de commande (comme indiqué ailleurs).

Sur une note: the Zend Framework already has an extensive number of Validators you can build on. Puisque ZF est une bibliothèque de composants, vous pouvez les utiliser sans avoir à migrer l'ensemble de votre application vers ZF.

2

Habituellement, vous faites ce genre de choses en utilisant le modèle d'usine, quelque chose comme ceci:

class ValidatorFactory { 
    public static function get($type) { 
     $validator = "Validator_$type"; 
     return new $validator(); 
    } 
} 

$valid = ValidatorFactory::get('mobile')->validate($number); 

AURAIT bien sûr besoin d'une vérification des erreurs et autres, mais vous devriez obtenir l'idée

0
... 
public function type($type) { 
    return new self($type); 
} 
... 

Remarque: Celui-ci renvoie chaque fois une nouvelle instance de votre classe Validator. Il serait donc préférable d'utiliser le modèle Factory comme suggéré par Dennis ou de ne pas lier le nouveau Validator à la méthode type().