2009-10-29 13 views
6

Attualmente sto lavorando su un'applicazione OO PHP. Ho una classe chiamata convalida che vorrei utilizzare per verificare che tutti i dati inviati siano validi, ma ovviamente ho bisogno di un posto dove definire le regole per ogni proprietà da controllare. Al momento, sto usando gli array durante la costruzione di un nuovo oggetto. es .:PHP Object Validation

$this->name = array(
'maxlength' => 10, 
'minlength' => 2, 
'required' => true, 
'value' => $namefromparameter 
) 

Una serie per ogni proprietà.

Chiamerei quindi un metodo statico della classe di convalida che eseguirà vari controlli in base ai valori definiti in ciascun array.

Esiste un modo più efficiente per farlo? Qualche consiglio apprezzato. Grazie.

risposta

8

So che l'array associativo viene utilizzato comunemente per configurare le cose in PHP (si chiama modello magic container ed è considerato una cattiva pratica, btw), ma perché non si creano più classi di convalida, ognuna delle quali in grado di gestirne una regola? Qualcosa di simile a questo:

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

$validators[] = new StringLengthValidator(2, 10); 
$validators[] = new NotNollValidator(); 
$validators[] = new UsernameDoesNotExistValidator(); 

Questo ha molteplici vantaggi rispetto l'implementazione utilizzando matrici:

  • È possibile documento loro (molto importante), PHPDoc possibile non analizzare commenti per le chiavi degli array.
  • il codice diventa typo-safe (array('reqiured' => true))
  • È completamente OO e non introduce nuovi concetti
  • E 'più leggibile (anche se molto più verboso)
  • L'attuazione di ogni vincolo può essere trovato in modo intuitivo (non è in una funzione 400-line, ma nella classe corretta)

EDIT: Ecco un link to an answer I gave ad un different question, ma che è per lo più applicabile a questo pure.

+0

Buon punto lì con la documentazione! –

+0

Grazie, non avevo mai sentito parlare di interfacce. Li controllerò fuori! – Dan

0

Dal momento che l'utilizzo di OO sarebbe più pulito se si utilizza classi per la convalida delle proprietà. Per esempio.

class StringProperty 
{ 
    public $maxLength; 
    public $minlength; 
    public $required; 
    public $value; 
    function __construct($value,$maxLength,$minLength,$required) 
    { 
    $this->value = $value; 
    $this-> maxLength = $maxLength; 
    $this-> minLength = $minLength; 
    $this-> required = $required; 
    } 
    function isValidat() 
    { 
    // Check if it is valid 
    } 
    function getValidationErrorMessage() 
    { 
    } 
} 

$this->name = new StringProperty($namefromparameter,10,2,true); 
if(!$this->name->isValid()) 
{ 
    $validationMessage = $this->name-getValidationErrorMessage(); 
} 

Utilizzo di una classe ha il vantaggio di incapsulare logica interna di esso che la matrice (fondamentalmente una struttura) non ha.

0

Forse ispirarsi allo Zend-Framework Validation.

Quindi definire un maestro:

class BaseValidator { 
    protected $msgs = array(); 
    protected $params = array();  

    abstract function isValid($value); 
    public function __CONSTRUCT($_params) { 
     $this->params = $_params; 
    } 
    public function getMessages() { 
     // returns errors-messages 
     return $this->msgs; 
    } 
} 

E poi costruire i validatori personalizzati:

class EmailValidator extends BaseValidator { 
    public function isValid($val=null) { 
     // if no value set use the params['value'] 
     if ($val==null) { 
      $val = $this->params['value']; 
     } 
     // validate the value 
     if (strlen($val) < $this->params['maxlength']) { 
      $this->msgs[] = 'Length too short'; 
     } 
     return count($this->msgs) > 0 ? false : true; 
    } 
} 

Infine l'array inital potrebbe diventare qualcosa di simile:

$this->name = new EmailValidator(
     array(
      'maxlength' => 10, 
      'minlength' => 2, 
      'required' => true, 
      'value' => $namefromparameter, 
     ), 
    ), 
); 

convalida potrebbe quindi essere Fatto così:

if ($this->name->isValid()) { 
    echo 'everything fine'; 
} else { 
    echo 'Error: '.implode('<br/>', $this->name->getMessages()); 
}