Páginas

lunes, 14 de marzo de 2011

clase validación de datos

Buenas un poco abandonado el blog el día de hoy compartire una clase que realice para hacer validaciones, esta clase surge de un tema que planteaba en forosdelweb por una duda correspondiente al patrón MVC, según tenía entendido por un poco de experiencia con el framework cakePHP, la lógica de nuestros sistemas se encuentra en el controlador según entendia yo :-), resulta que esto era un error de concepto que tenia y los amigos del foro me ayudaron a entender y ver este error, luego de entender este concepto me genero otra duda donde realizar las validaciones?? en el controlador?? en el modelo?? según mi criterio si en el patrón MVC toda la lógica y el trabajo con los datos se hace con el modelo entonces las validaciones de los datos deve de ser en el modelo, entonces me dispuse a crear una clase para hacer las validaciones es una primera versión que hace la validación de manera correcta lo unico que se debe es llamar al método de la clase e indicar los parámetros para realizar la validacion

/**
/**
* Clase para realizar validaciones en el modelo
* Es utilizada para realizar validaciones en el modelo de nuestras clases.
*
* @author Carlos Belisario
*/
class Validacion
{
 protected $_atributos;
 protected $_error;
 public $mensaje;
 
 /**
 * Metodo para indicar la regla de validacion
 * El método retorna un valor verdadero si la validación es correcta, de lo contrario retorna el objeto 
 * actual, permitiendo acceder al atributo Validacion::$mensaje ya que es publico
 */
 public function rules($rule = array(),$data)
 {
  
  if(!is_array($rule)){
   $this->mensaje = "las reglas deben de estar en formato de arreglo";
   return $this;
  }  
  foreach($rule as $key => $rules){
   $reglas = explode(',',$rules['regla']);
   if(array_key_exists($rules['name'],$data)){
    foreach($data as $indice => $valor){     
     if($indice === $rules['name']){
      foreach($reglas as $clave => $valores){ 
       $validator = $this->_getInflectedName($valores);        
       if(!is_callable(array($this, $validator))){
          throw new BadMethodCallException("No se encontro el metodo actual");
       }
       $respuesta = $this->$validator($rules['name'], $valor);        
      }
      break;
     }
    }
   }
   else{
    $this->mensaje[$rules['name']] = "el campo $value no esta dentro de la regla de validación o en el formulario";    
   }
  }  
  if(!$respuesta){
   return $this;
  }
  else{
   return true;
  }
 } 
 
 /**
 * Metodo inflector de la clase 
 * por medio de este metodo llamamos a las reglas de validacion que se generen
 */
 private function _getInflectedName($text)
 {
  $_validator = preg_replace('/[^A-Za-z0-9]+/',' ',$text);
  $arrayValidator = explode(' ',$_validator);    
  if(count($arrayValidator) > 1){
   foreach($arrayValidator as $key => $value){     
    if($key == 0){
     $validator .= "_".$value; 
    }
    else{     
     $validator .= ucwords($value);
    }
   }
  }
  else{
   $validator = "_".$_validator;
  }    
  return $validator;
 }
  
 /**
 * Metodo de verificacion de que el dato no este vacio o NULL
 * El metodo retorna un valor verdadero si la validacion es correcta de lo contrario retorna un valor falso
 * y llena el atributo validacion::$mensaje con un arreglo indicando el campo que mostrara el mensaje y el 
 * mensaje que visualizara el usuario
 */
 protected function _noEmpty($campo,$valor)
 {   
  if(isset($valor) && !empty($valor)){   
   return true;   
  }
  else{   
   $this->mensaje[$campo][] = "el campo $campo debe de estar lleno";
   return false;
  }
 }
 /**
 * Metodo de verificacion de tipo numerico
 * El metodo retorna un valor verdadero si la validacion es correcta de lo contrario retorna un valor falso
 * y llena el atributo validacion::$mensaje con un arreglo indicando el campo que mostrara el mensaje y el 
 * mensaje que visualizara el usuario
 */
 protected function _numeric($campo,$valor)
 {   
  if(is_numeric($valor)){
   return true;
  }  
  else{
   $this->mensaje[$campo][] = "el campo $campo debe de ser numerico";
   return false;
  }
 }
 
 /**
 * Metodo de verificacion de tipo email
 * El metodo retorna un valor verdadero si la validacion es correcta de lo contrario retorna un valor falso
 * y llena el atributo validacion::$mensaje con un arreglo indicando el campo que mostrara el mensaje y el 
 * mensaje que visualizara el usuario
 */
 protected function _email($campo,$valor)
 {
  if(preg_match("/^[a-z]+([\.]?[a-z0-9_-]+)*@[a-z]+([\.-]+[a-z0-9]+)*\.[a-z]{2,}$/",$valor)){     
   return true;
  } 
  else{
   $this->mensaje[$campo][] = "el campo $campo de estar en el formato de email usuario@servidor.com";
   return false;
  }
 }
}
el uso de la clase es muy sencillo aca dejo las pruebas que realice a la clase

$_POST['campo1'] = 1;
$_POST['campo2'] = "usuario@hotmail.com";
$datos = $_POST;
$validacion =  new Validacion();
$regla = array(
   array('name'=>'campo1','regla'=>'no-empty,numeric'),
   array('name'=>'campo2','regla'=>'no-empty,email')
  );
$validaciones = $validacion->rules($regla,$datos);
print_r($validaciones);

por ahora solo tengo tres reglas de validación son muy básicas y sencillas, espero que sea de su agrado si tienen alguna corrección o critica que hacer a la clase no hay ningun problema, saludos

9 comentarios:

  1. Me gusta porque yo estoy haciendo una clase para validaciones con PHP y es más o menos como mi idea.

    Estamos en contacto.

    ResponderEliminar
  2. Esta padre tu clase, es parecida a una que estoy creando para validad formularios del lado del servidor con PHP

    ResponderEliminar
  3. Gracias por el comentario, si te fijas solo son validaciones sencillas, lo que hay que hacer es agregar mas metodos con reglas de validaciones, si tienes alguna mejora la puedes publicar por aca si no es problema para ti por supuesto, gracias por el comentario, saludos

    ResponderEliminar
  4. Ok, no hay problema. Gracias a ti por compartir con los demás tus conocimientos. La clase de validación que estoy realizando es con Clases que implementan una Interface, por lo que es un poco compleja porque se usa polimorfismo.

    ResponderEliminar
  5. bueno si hay clases que son mas complejas e implementan muchos mas métodos y por supuesto hay mas reglas de validaciones por lo que son mas complejas, yo la hice lo mas simple que pude hacerla ya que era lo que necesitaba en el momento de crearla, sería interesante ver el diseño de tu clase, si tienes un link donde podamos verlas para ver otra implementación de este tipo de clases sería excelente, saludos y gracias por el comentario

    ResponderEliminar
  6. Muy buena la clase, aunque, si mal no recuerdo, ahora hay filtros de validación. Se podría adaptar la clase a ellos ¿no? ¡Un abrazo y gracias por compartir sus conocimientos con nosotros!

    ResponderEliminar
  7. Si a partir de 5.2+ tenemos el http://php.net/manual/es/function.filter-var.php, que nos permite realizar validaciones más simplemente, se pudiera hacerle modificaciones a la clase, saludos

    ResponderEliminar
  8. La idea esta muy bien amigo pero tiene un pequeño detalle, y es que evaluas unicamente el ultimo filtro,

    if(!$respuesta){
    return $this;
    }

    esto lo tienes fuera del foreach por lo que si el ultimo es true y los demas false, aun asi dara resultado true

    1.- puedes meter esto dentro del foreach y cortar el ciclo apenas encuentre un error y retornarlo.

    2.- puedes crear una variable que cuando detecte un error cambie a false y sea la que

    if($x){//en lugar de $respuesta
    return $this;
    }

    ResponderEliminar