Validación de Formularios
Antes de explicar la aproximación de CodeIgniter a la validación de datos, describamos el escenario ideal:
- Un formulario es mostrado.
- Se llena y se envía.
- Si envió algo inválido, o quizás se olvidó de un item requerido, el formulario es vuelto a mostrar conteniendo sus datos, junto con un mensaje de error que describa el problema.
- Este proceso continúa hasta haber envíado un formulario válido.
En la recepción final, el script debe:
- Chequear datos requeridos.
- Verificar que los datos sean de tipo correcto, y cumplan el criterio correcto. (Por ejemplo si se envia un nombre de usuario debe ser validado para contener sólo caracteres permitidos. Debe tener un largo mínimo, y no exceder un largo máximo. El nombre de usuario no puede ser el mismo de un usuario existente, o quizás una palabra reservada. Etc.)
- Limpiar los datos por seguridad.
- Pre-formatear los datos si es necesario (Necesita limpiar los espacios? Encodear en HTML? Etc.)
- Preparar los datos para insertar en la base de datos.
Aunque no hay nada complejo acerca del proceso, usualmente requiere una significativa cantidad de código, y para mostrar mensajes de errores, varias estructuras de control que usualmente se ubican en el formulario HTML. La validación de formulario, aunque es simple de crear, es generalmente muy poco prolija y tediosa de implementar.
CodeIgniter provee una comprensiva validación que verdaderamente minimiza la cantidad de código que escribirá. También remueve todas las estructuras de control de su formulario HTML, permitiéndole ser limpio y libre de código.Visión General
Para implementar la clase de validación de CodeIgniter necesitará tres cosas:
- Un archivo Vista que contenga el formulario.
- Un archivo de Vista que contenga un mensaje de "éxito" para ser mostrado cuando el envío es exitoso.
- Una función controlador que recibe y procesa los datos enviados.
Creemos estas tres cosas, usando un formulario de inscripción de miembros como ejemplo.
EL Formulario
Usando un editor de texto, cree un formulario llamado miformulario.php. En él, ubique este código y guárdelo en su carpeta applications/views/:
Página de Éxito
Usando un editor de texto, cree un formulario llamado formulario_exito.php. En él, ubique este código y guárdelo en la carpeta applications/views/:
El Controlador
Usando un editor de texto, cree un controlador llamado formulario.php. En él, ubique este código y guárdelo en su carpeta applications/controllers/:
Inténtelo!
Para probar su formulario, visite su sitio usando una URL similar a esta:
www.su-sitio.com/index.php/formulario/
Si usted envía el formulario debería simplemente ver el formulario recargado. Eso es porque ninguna regla de validación ha sido establecida aún, lo que haremos en un momento.
Explicación
Notará varias cosas acerca de las páginas anteriores:
El formulario (miformulario.php) es un formulario web estándar, con un par de excepciones:
- Usa el asistente de formulario para crear la apertura del formulario. Técnicamente, esto no es necesario. Puede crear el formulario usando HTML estándar. Sin embargo, el beneficio de usar este asistente es que genera la URL de acción por usted, basado en la URL en su archivo de configuración. Esto hace que su aplicación sea más portable y flexible en caso de que sus URLs cambien.
- Al comienzo del formulario notará la siguiente variable:
<?=$this->validation->error_string; ?>Esta variable mostrará cualquier mensaje de error enviado por el validador. Si no hay mensajes, no devolverá nada.
El controlador (formulario.php) tiene una función: index(). Esta función inicializa la clase de validación, carga el asistente de formulario y asistente de URL usado por sus archivos de vista. También corre la rutina de validación. Basado en si la validación fue exitosa presenta el formulario o la página de éxito.
Como no ha dicho a la clase de validación que valide nada, devuelve "falso" (boolean false) por defecto. La función run() sólo devuelve "verdadero" si ha aplicado éxitosamente sus reglas sin que ninguna halla fallado.
Estableciendo Reglas de Validación
CodeIgniter le permite establecer tantas reglas de validación como necesita para un campo dado, encascándolos en orden, e incluso le permite preparar y pre-procesar los datos de los campos al mismo tiempo. Veámoslo en acción, lo explicaremos luego.
En su controlador (formulario.php), agrega este código justo debajo de la función de inicialización de validación:
$reglas['usuario'] = "required";
$reglas['contrasena'] = "required";
$reglas['conf_contrasena'] = "required";
$reglas['email'] = "required";
$this->validation->set_rules($reglas);
Su controlador ahora debería verse así:
Ahora envíe el formulario con los campos en blanco y debería ver el mensaje de error. Si envía el formulario con todos los campos rellenados, verá la página de éxito.
Nota: Los campos del formulario no están aún rellenados con los datos cuando hay un error. Empezaremos con eso en poco, una vez que hayamos terminado de explicar las reglas de validación.
Cambiando los Delimitadores de Error
Por defecto, el sistema agrega una etiqueta de párrafo (<p>) alrededor de cada mensaje de error mostrado. Puede fácilmente cambiar estos delimitadores con este código, ubicado en su controlador:
$this->validation->set_error_delimiters('<div class="error">', '</div>');
En este ejemplo, hemos cambiado para usar etiquetas div.
Reglas en Cascada
CodeIgniter le permite encadenar múltiples reglas con pipes(|). Intentémoslo. Cambie su arreglo de reglas así:
$reglas['usuario'] = "required|min_length[5]|max_length[12]";
$reglas['contrasena'] = "required|matches[conf_contrasena]";
$reglas['conf_contrasena'] = "required";
$reglas['email'] = "required|valid_email";
The above code requires that:
- El campo usuario debe ser no más corto de 5 caracteres y no más de 12.
- El campo contraseña debe coincidir con el campo de confirmación de contraseña.
- El campo email debe contener una dirección de email válida.
Inténtelo!
Nota: Hay numerosas reglas disponibles las cuales pueden ser leídas en la referencia de validación.
Preparando Datos
Además de las funciones de validación como las usadas anteriormente, puede preparar los datos de varias formas. Por ejemplo, puede establecer reglas así:
$reglas['usuario'] = "trim|required|min_length[5]|max_length[12]|xss_clean";
$reglas['contrasena'] = "trim|required|matches[conf_contrasena]|md5";
$reglas['conf_contrasena'] = "trim|required";
$reglas['email'] = "trim|required|valid_email";
En el anterior ejemplo, estamos "limpiando" los campos, convirtiendo la contraseña a MD5, y corriendo al usuario a través de la función "xss_clean", la que remueve datos maliciosos.
Cualquier función nativa de PHP que acepte un parámetro puede ser usada como regla, como htmlspecialchars, trim, MD5, etc.
Nota: Generalmente querrá usar las funciones de preparación después de las reglas de validación, así si hay un error, los datos originales serán mostrados en el formulario.
Funciones de retorno (callback): Sus propias Funciones de Validación
El sistema de validación soporta llamadas de retorno a sus propias funciones de validación. Esto permite extender la clase de validación para concretar sus necesidades. Por ejemplo, si desea correr una consulta de base de datos para ver si el usuario está eligiendo un nombre de usuario único, puede crear una función callback que lo haga. Creemos un ejemplo simple.
En su controlador, cambie la regla "usuario" a esto:
$reglas['usuario'] = "callback_usuario_check";
Luego agregue una nueva función llamada usuario_check a su controlador. Así es como su controlador debería verse:
Recargue su formulario y envíelo con la palabra "test" como el usuario. Puede ver que el dato del campo del formulario fue pasado a su función de retorno para su procesamiento.
Para invocar una llamada de retorno sólo ponga el nombre de la función en una regla, con "callback_" como prefijo de la regla.
El mensaje de error fue establecido usando la función $this->validation->set_message. Simplemente recuerde que la clave del mensaje (el primer parámetro) debe coincidir con su nombre de función.
Nota: Puede aplicar su propio mensaje de error a cualquier regla, sólo al escablecer el mensaje, similarmente. Por ejemplo, para cambiar el mensaje para la regla "required" haría esto:
$this->validation->set_message('required', 'Su mensaje personal aquí');
Re-populando el formulario
Hasta aquí sólo hemos tratado con errores. Es tiempo de repopular los campos del formulario con los datos enviados. Esto es hecho de manera similar a sus reglas. Agregue este código a su controlador, justo debajo de sus reglas:
$fields['usuario'] = 'Usuario';
$fields['contrasena'] = 'Contraseña';
$fields['conf_contrasena'] = 'Confirmación de Contraseña';
$fields['email'] = 'Dirección de Email';
$this->validation->set_fields($fields);
Las claves del arreglo son los nombre de los campos del formulario, el valor representa el nombre completo que quiere mostrar en el mensaje de error.
La función índice del controlador debería verse así ahora:
Ahora abra su archivo de vista miformulario.php y actualice el valor en cada campo para que tenga un atributo del objeto correspondiente a su nombre:
Ahora recargue su página y envíe el formulario de manera que dispare un error. Sus campos de formulario deben ser populados y los mensajes de error contendrán un nombre de campo más relevante.
Mostrando Errores Individualmente
Si prefiere mostrar un mensaje de error próximo a cada campo del formulario, en vez de como una lista, puede cambiar su formulario para que se vea así:
Si no hay errores, nada será mostrado. Si hay un error, el mensaje aparecerá, encerrado en los delimitadores que haya establecido (las etiquetas <p> por defecto).
Nota: Para mostrar errores de esta forma debe recordar establecer sus campos usando la función
$this->validation->set_fields descripta anteriormente. Los errores serán transformados en variable, que hace "_error" después del nombre de campo.
Por ejemplo, el error de "usuario" estará disponible en:
$this->validation->usuario_error.
Referencia de Reglas
La siguiente es una lista de todas las reglas nativas que están disponibles para usar:
| Regla | Parámetro | Descripción | Ejemplo |
|---|---|---|---|
| required | No | Devuelve FALSE si el elemento del formulario es vacío. | |
| matches | Sí | Devuelve FALSE si el elemento del formulario no coincide con el del parámetro. | matches[item_formulario] |
| min_length | Sí | Devuelve FALSE si el elemento del formulario es más corto que el valor del parámetro. | min_length[6] |
| max_length | Sí | Devuelve FALSE si el elemento del formulario es más largo que el valor del parámetro. | max_length[12] |
| exact_length | Sí | Devuelve FALSE si el largo del elemento del formulario no es exactamente el del valor del parámetro. | exact_length[8] |
| alpha | No | Devuelve FALSE si el elemento del formulario contiene algo distinto que caracteres del alfabeto. | |
| alpha_numeric | No | Devuelve FALSE si el elemento del formulario contiene algo distinto que caracteres alfanuméricos. | |
| alpha_dash | No | Devuelve FALSE si el elemento del formulario contiene algo que no sean caracteres alfanuméricos, guiones bajos o guiones. | |
| numeric | No | Devuelve FALSE si el elemento del formulario contiene algo distinto a caracteres numéricos. | |
| integer | No | Devuelve FALSE si el elemento del formulario contiene algo distinto a un entero. | |
| valid_email | No | Devuelve FALSE si el elemento del formulario no contiene una dirección de email válida. | |
| valid_ip | No | Devuelve FALSE si la IP suministrada no es válida. | |
| valid_base64 | No | Devuelve FALSE si la cadena suministrada contiene algún caracter distinto a los caracteres válidos de Base64. |
Nota: Estas reglas pueden ser también llamadas como funciones discretas. Por ejemplo:
$this->validation->required($cadena);
Nota: Puede usar también cualquier función de PHP que permita un parámetro.
Prepping Reference
La siguiente es una lista de todas las funciones de preparación que están disponibles para usar:
| Nombre | Parámetro | Descripción |
|---|---|---|
| xss_clean | No | Corre el dato a través de la función de filtro XSS, descripta enla página de la Clase de Entrada. |
| prep_for_form | No | Conviernte caracteres especiales para que los datos HTML puedan ser mostrados en un campo de formulario sin romperlo. |
| prep_url | No | Agrega "http://" a la URLs si no lo tienen. |
| strip_image_tags | No | Quitan las etiquetas de imagen de HTML dejando la URL plata. |
| encode_php_tags | No | Convierte las etiquetas PHP a entidades. |
Nota: Puede también usar cualquier función nativa de PHP que permita un parámetro, como trim, htmlspecialchars, urldecode, etc.
Estableciendo Mensajes de Error Especiales
Todos los mensajes ed error nativos están ubicados en el siguiente archivo de lenguaje: language/english/validation_lang.php
Para establecer sus propios mensajes puede o editar ese archivo, o utilizar la siguiente función:
$this->validation->set_message('regla', 'Mensaje de Error');
Donde regla corresponde al nombre de la regla en perticular, y Mensaje de Error es el texto que quiere mostrar.
Tratando con Menú desplegable y casillas de verificación (radio y checkbox)
Si usa un menú desplegable, casillas de verificación (radio y checkbox), querrá el estado de esos items que sea retenido en el caso de un error. La clase de Validación tiene tres funciones que ayudan a esto:
set_select()
Permite mostrar el item del menú que fue seleccionado. El primer parámetro debe contener el nombre del menú de selección, el segundo parámetro debe contener el valor de cada item. Ejemplo:
<select name="miselect">
<option value="uno" <?= $this->validation->set_select('miselect', 'uno'); ?> >Uno</option>
<option value="dos" <?= $this->validation->set_select('miselect', 'dos'); ?> >Dos</option>
<option value="tres" <?= $this->validation->set_select('miselect', 'tres'); ?> >Tres</option>
</select>
set_checkbox()
Permite mostrar una casilla de verificación (checkbox) en el estado que fue enviada. El primer parámetro debe contener el nombre de la casilla, el segundo parámetro debe contener su valor. Ejemplo:
<input type="checkbox" name="micheck" value="1" <?= $this->validation->set_checkbox('micheck', '1'); ?> />
set_radio()
Permite mostrar una casilla de verificación (checkbox) en el estado que fue enviada. El primer parámetro debe contener el nombre de la casilla, el segundo parámetro debe contener su valor. Ejemplo:
<input type="radio" name="miradio" value="1" <?= $this->validation->set_radio('miradio', '1'); ?> />