Ver Mensaje Individual
  #1 (permalink)  
Antiguo 06/11/2013, 02:48
Avatar de Alexis88
Alexis88
Philosopher
 
Fecha de Ingreso: noviembre-2011
Ubicación: Tacna, Perú
Mensajes: 5.552
Antigüedad: 12 años, 6 meses
Puntos: 977
Problema al intentar guardar datos

Hola amigos, mi problema es el siguiente:

Tengo un sencillo formulario en el que el usuario debe de ingresar sus datos personales, éstos son validados mediante expresiones regulares para evitar inyecciones SQL o de otro tipo y finalmente son enviados a un archivo que realiza la llamada del respectivo procedimiento almacenado creado en una BD en MySQL. Además de este procedimiento almacenado (de ahora en adelante PA), hay otros dos más que utilizo para llenar datos en dos combos, éstos trabajan sin problemas, no así el PA con el que intento guardar los datos.

La estructura del formulario es la siguiente:
Código PHP:
Ver original
  1. <?php
  2. //Aquí incluyo el archivo de conexión y el que realiza las consultas a la BD
  3. ?>
  4. <form id = "miFormulario" name = "miFormulario" action = "procesar.php" method = "POST">
  5.     <section id = "labels">
  6.         <label for = "nombre" accessKey = "nombre">Nombre</label>
  7.         <label for = "apellidos" accessKey = "apellidos">Apellidos</label>
  8.         <label for = "email" accessKey = "email">E-Mail</label>
  9.         <label for = "domicilio" accessKey = "domicilio">Domicilio</label>
  10.         <label for = "fechanac" accessKey = "fechanac">Fecha de nacimiento</label>
  11.         <label for = "pais" accessKey = "pais">País</label>
  12.     </section>
  13.     <section id = "inputs">        
  14.         <!-- Nombre -->
  15.         <input type = "text" id = "nombre" name = "nombre" size = "20" placeholder = "Ingrese su nombre" pattern = "^[A-ZÁÉÍÓÚÑÜ]+[a-záéíóúÜüÑñA-ZÁÉÍÓÚ\.' ]{2,150}" required title = "Debe de ingresar caracteres típicos en el nombre de una persona" autofocus />
  16.                
  17.         <!-- Apellidos -->
  18.         <input type = "text" id = "apellidos" name = "apellidos" size = "20" placeholder = "Ingrese sus apellidos" pattern = "^[A-ZÁÉÍÓÚÑ]+[a-záéíóúÑñA-ZÁÉÍÓÚ\.' ]{2,150}" required title = "Debe de ingresar caracteres típicos en los apellidos de una persona" />      
  19.                
  20.         <!-- E-Mail -->
  21.         <input type = "email" id = "email" name = "email" size = "25" placeholder = "Ingrese su E-Mail" required title = "Debe de ingresar un E-Mail válido, ej. [email protected]" />
  22.                
  23.         <!-- Domicilio -->
  24.         <input type = "text" id = "domicilio" name = "domicilio" size = "30" placeholder = "Ingrese la dirección de su domicilio"  required title = "Debe de ingresar caracteres típicos en el nombre de una persona" />
  25.            
  26.         <!-- Fecha de nacimiento -->
  27.         <input type = "date" id = "fechanac" name = "fechanac" required title = "Debe de seleccionar la fecha de su nacimiento" />
  28.            
  29.         <!-- Pais -->
  30.         <?php
  31.         $buscarPais = $miConsulta->paises($miConexion->conexion);
  32.         if (mysqli_num_rows($buscarPais)) {
  33.         ?>
  34.             <select id = "pais" name = "pais" required title = "Debe de seleccionar el país en donde nació">
  35.                 <option></option>
  36.         <?php
  37.             while ($datosPais = mysqli_fetch_array($buscarPais)) {
  38.         ?>
  39.                 <option value = "<?=$datosPais["codigo"]?>"><?=utf8_encode($datosPais["nombre"])?></option>
  40.         <?php
  41.             }
  42.         ?>
  43.             </select>
  44.         <?php
  45.         } else
  46.             echo "No se encontraron países en la base de datos";
  47.         ?>
  48.     </section>
  49.  
  50.     <!-- Ciudad -->
  51.     <div id = "divCiudad">
  52.         <section id = "labelCiudad">
  53.             <label for = "ciudad" accessKey = "ciudad">Ciudad</label>
  54.         </section>
  55.  
  56.         <section id = "inputCiudad"></section>
  57.     </div>
  58.  
  59.     <!-- Botón Guardar -->
  60.     <input type = "submit" id = "guardar" name = "guardar" value = "Guardar" />
  61. </form>

El archivo procesar.php, que es el que recibe los datos ingresados en el formulario, contiene lo siguiente:
Código PHP:
Ver original
  1. <?php
  2. //Aquí incluyo a los archivos de la conexión a la BD, el que realiza las consultas a la BD, el que desinfecta los datos de entrada (usé [URL="http://css-tricks.com/snippets/php/sanitize-database-inputs/"][B][COLOR="Blue"]este script[/COLOR][/B][/URL]) y el que realiza las validaciones
  3.  
  4. //Código
  5. if (!($miConsulta->codigo($miConexion->conexion, $codigo = $scripts->codigo())))
  6.     do {
  7.         $codigo = $scripts->codigo();
  8.     } while ($miConsulta->codigo($miConexion->conexion, $codigo));
  9.  
  10. //Nombre
  11. $nombre = (strlen($_POST["nombre"]) && isset($_POST["nombre"]) && !is_null($_POST["nombre"])) ? $scripts->validarNomApe($desinfectar->sanitize($miConexion->conexion, $_POST["nombre"])) : $scripts->formulario();
  12. if (is_null($nombre)) $scripts->formulario("Debe de ingresar su nombre en un formato válido");
  13.  
  14. //Apellidos
  15. $apellidos = (strlen($_POST["apellidos"]) && isset($_POST["apellidos"]) && !is_null($_POST["apellidos"])) ? $scripts->validarNomApe($desinfectar->sanitize($miConexion->conexion, $_POST["apellidos"])) : $scripts->formulario();
  16. if (is_null($apellidos)) $scripts->formulario("Debe de ingresar sus apellidos en un formato válido");
  17.  
  18. //E-Mail
  19. $email = (strlen($_POST["email"]) && isset($_POST["email"]) && !is_null($_POST["email"])) ? $scripts->validarEMail($desinfectar->sanitize($miConexion->conexion, $_POST["email"])) : $scripts->formulario();
  20.  
  21. if (is_null($email))
  22.     $scripts->formulario("Debe de ingresar su E-Mail en un formato válido");
  23. else if ($miConsulta->email($miConexion->conexion, $email)) {
  24.     $scripts->formulario("El E-Mail ingresado se encuentra registrado. Por favor, ingrese otro.");
  25.     $email = NULL;
  26. }
  27.  
  28. //Domicilio
  29. $domicilio = (strlen($_POST["domicilio"]) && isset($_POST["domicilio"]) && !is_null($_POST["domicilio"])) ? $scripts->validarDomicilio($desinfectar->sanitize($miConexion->conexion, $_POST["domicilio"])) : $scripts->formulario();
  30. if (is_null($domicilio)) $scripts->formulario("Debe de ingresar su dirección domiciliaria en un formato válido y utilizando menos de 256 caracteres");
  31.  
  32. //Fecha de nacimiento
  33. $fechanac = (strlen($_POST["fechanac"]) && isset($_POST["fechanac"]) && !is_null($_POST["fechanac"])) ? $scripts->validarFechNac($desinfectar->sanitize($miConexion->conexion, $_POST["fechanac"])) : $scripts->formulario();
  34. if (is_null($fechanac)) $scripts->formulario("Debe de ingresar la fecha de su nacimiento en un formato válido");
  35.  
  36. //País
  37. $pais = (strlen($_POST["pais"]) && isset($_POST["pais"]) && !is_null($_POST["pais"])) ? $scripts->validarPaisCiudad($desinfectar->sanitize($miConexion->conexion, $_POST["pais"])) : $scripts->formulario();
  38. if (is_null($pais)) $scripts->formulario("Debe de elegir un país de la lista");
  39.  
  40. //Ciudad
  41. $ciudad = (strlen($_POST["ciudad"]) && isset($_POST["ciudad"]) && !is_null($_POST["ciudad"])) ? $scripts->validarPaisCiudad($desinfectar->sanitize($miConexion->conexion, $_POST["ciudad"])) : $scripts->formulario();
  42. if (is_null($ciudad)) $scripts->formulario("Debe de elegir una ciudad de la lista");
  43.  
  44. //Añadimos todos los datos a un array que será enviado a la función de procesamiento de datos
  45. $datos = array(
  46.             "codigo" => $codigo,
  47.             "nombre" => $nombre,
  48.             "apellidos" => $apellidos,
  49.             "email" => $email,
  50.             "domicilio" => $domicilio,
  51.             "fechanac" => $fechanac,
  52.             "pais" => $pais,
  53.             "ciudad" => $ciudad
  54.         );
  55.        
  56. $bandera = true; //Comodín para determinar si se guardarán o no los datos
  57. foreach ($datos as $dato)
  58.     if (is_null($dato)) {
  59.         $bandera = false;
  60.         break;
  61.     }
  62.  
  63. if ($bandera)
  64.     //Guardamos los datos del formulario en la Base de datos
  65.     if ($miConsulta->guardarForm($miConexion->conexion, $datos))
  66.         echo "Los datos han sido guardados satisfactoriamente";
  67.     else
  68.         echo "Ha ocurrido un error al intentar guardar los datos";
  69. ?>

La validación (del lado del servidor) la realizo de este modo:
Código PHP:
Ver original
  1. <?php
  2. class Cls_Scripts {
  3.     public $codigo;
  4.     public $respuesta;
  5.  
  6.     function formulario($mensaje) {
  7.         echo $mensaje ? $mensaje . "<br />" : "Se produjo un error durante el procesamiento de los datos";
  8.     }
  9.  
  10.     function codigo() {
  11.         $this->codigo = "";
  12.         for ($i = 0; $i < 10; $i++)
  13.             $this->codigo .= mt_rand(0, 9); //Genera un código de 10 dígitos aleatorios entre el 0 y el 9
  14.  
  15.         return $this->codigo;
  16.     }
  17.  
  18.     function validarNomApe($contenido) {
  19.         $exreg = "/^[A-ZÁÉÍÓÚÑÜ]+[a-záéíóúÜüÑñA-ZÁÉÍÓÚ\.' ]{2,150}$/si";
  20.         return preg_match($exreg, $contenido) ? $contenido : NULL;
  21.     }
  22.  
  23.     function validarEMail($contenido) {
  24.         $exreg = "/^([\w_\.-]+)@([\w\.-]+)\.([a-z\.]{2,6})$/si";
  25.         return preg_match($exreg, $contenido) ? $contenido : NULL;
  26.     }
  27.  
  28.     function validarDomicilio($contenido) {
  29.         $exreg = "/^[\<\>\\\{\}\[\]]*$/";
  30.         return !preg_match($exreg, $contenido) ? $contenido : NULL;
  31.     }
  32.  
  33.     function validarFechNac($contenido) {
  34.         $exreg = "/\d{4}-\d{2}-\d{2}/";
  35.         $this->respuesta = true;
  36.  
  37.         if (preg_match($exreg, $contenido)) { //Si el formato de fecha es válido
  38.             list($year, $month, $day) = explode("-", $contenido);          
  39.             $bandera; //Comodín para la verificación del mes (cuando no es Febrero)
  40.             if (($year % 4 == 0 && $year % 100 != 0) || $year % 400 == 0) { //Año bisiesto
  41.                 if ($month == 2 && !($day <= 29 && $day > 0)) //Febrero
  42.                     $this->respuesta = false;
  43.                 else //Año no bisiesto
  44.                     if ($month == 2 && !($day <= 29 && $day > 0)) //Febrero
  45.                         $this->respuesta = false;
  46.  
  47.                 //Otros meses
  48.                 switch ($month) {
  49.                     case 1: case 3: case 5: case 7: case 8: case 10: case 12:
  50.                         $bandera = 1;
  51.                     break;
  52.  
  53.                     case 4: case 6: case 9: case 11:
  54.                         $bandera = 2;
  55.                     break;
  56.                 }
  57.  
  58.                 //Si el mes tiene más de 31 o 30 días o si se ingresó una cantidad menor a 1
  59.                 if ($bandera == 1 && ($day > 31 || $day < 1))
  60.                     $this->respuesta = false;
  61.                 else if ($bandera == 2 && ($day > 30 || $day < 1))
  62.                     $this->respuesta = false;
  63.             }
  64.  
  65.         } else
  66.             $this->respuesta = false;
  67.  
  68.         return $this->respuesta ? $contenido : false;
  69.     }
  70.  
  71.     function validarPaisCiudad($contenido) {
  72.         $exreg = "/\d/";
  73.         return preg_match($exreg, $contenido) ? $contenido : NULL;
  74.     }
  75. }
  76. ?>