Hola amigos del foro, mi problema es el siguiente:
Estoy por terminar de hacer una pequeña aplicación en PHP, la cual guarda en una BD los datos ingresados en un formulario, para que este proceso sea seguro, valido los datos del lado del cliente con HTML5 y jQuery y del lado del servidor con PHP, en todos los casos siempre usando expresiones regulares, además, manejo con clases tanto a la conexión a la BD como las llamadas a las funciones que invocan a los procedimientos almacenados, es decir, hago uso de la POO.
Mi conexión la realizado de esta forma:
La clase que contiene los métodos que llaman a los procedimientos almacenados (de ahora en adelante PA), es la siguiente:
Y el archivo que recibe los datos del formulario e invoca a los métodos de la clase que llaman a los PA es esta:
Al parecer, después de la llamada al método codigo, la cual devuelve el resultado esperado, la variable $miConsulta que es la que representa a la clase en el archivo de procesos (el tercero), deja de funcionar, probé imprimiendo mensajes si es que se obtenía un resultado y la respuesta siempre fue negativa, por ejemplo en: echo $miConsulta->email($email) ? "TRUE" : "FALSE"; siempre se imprimía "FALSE", cuando utilizo la función mysqli_errno(), se muestra el código de error 2014 de descripción"Commands out of sync; you can't run this command now", incluso intenté hacer esto:
Se muestra el siguiente mensaje: "Fatal error: Call to a member function fetch_array() on a non-object in line 30", dicha línea es en donde se encuentra el ciclo While.
Como verán en el código, son 3 llamadas a 3 métodos de la clase, la primera llamara al método codigo, la segunda al método email y la tercera al método guardarForm, de las cuales, solamente la primera llamada me retorna el valor esperado, mientras que las otras dos no funcionan, sin embargo, si inhabilito a la primera llamada, es decir, a la del código, funciona la del email pero no la de guardarForm y recién cuando deshabilito la del email, funciona la de guardarForm. Otra forma en que funciona esto es creando una nueva instancia para la conexión y para la clase de esta forma:
Del modo mostrado arriba, funciona todo sin necesidad de inhabilitar ninguna llamada. Probé utilizando queries sencillas en lugar de procedimientos almacenados, pero el resultado es el mismo, con lo que todo apunta a que el problema radica en lo que les he explicado.
Cabe señalar que los métodos paises y ciudades, funcionan pues las llamadas que hago para cada uno de esos métodos, las realizo en diferentes archivos, instanciando en cada uno a la conexión y a la clase.
Ahora, mi pregunta es: ¿Por qué solamente puedo utilizar una vez a la variable que instancia a la clase con los métodos y solamente inhabilitando todas menos una, ésta que no es deshabilitada logra funcionar y por qué creando otras instancias para la clase, recién logran funcionar las tres llamadas a los métodos?
Saludos y, de antemano, gracias por su deferencia.
Estoy por terminar de hacer una pequeña aplicación en PHP, la cual guarda en una BD los datos ingresados en un formulario, para que este proceso sea seguro, valido los datos del lado del cliente con HTML5 y jQuery y del lado del servidor con PHP, en todos los casos siempre usando expresiones regulares, además, manejo con clases tanto a la conexión a la BD como las llamadas a las funciones que invocan a los procedimientos almacenados, es decir, hago uso de la POO.
Mi conexión la realizado de esta forma:
PHP:
<?php
class Cls_Conexion {
public $conexion;
public function __construct() {
//Conexión a la base de datos
$servidor = "localhost"; //Nombre del servidor
$usuario = "root"; //Nombre de usuario en tu servidor
$password = "miclave"; //Contraseña del usuario
$base = "bd_formulario"; //Nombre de la Base de Datos
//Se realiza la conexión
return $this->conexion = new mysqli($servidor, $usuario, $password, $base) or exit ("Se ha producido un error en la conexión al servidor");
}
function __destruct() {
$this->conexion->close();
}
}
?>
La clase que contiene los métodos que llaman a los procedimientos almacenados (de ahora en adelante PA), es la siguiente:
PHP:
<?php
class Cls_Consultas {
public $conexion;
function __construct($conex) {
$this->conexion = $conex;
}
function paises() {
return $this->conexion->query("CALL USP_listCountries()");
}
function ciudades($pais) {
return $this->conexion->query(sprintf("CALL USP_listCities(%d)", $pais));
}
function codigo($codigo) {
return $this->conexion->query(sprintf("CALL USP_validateCode('%s')", $codigo));
}
function email($email) {
return $this->conexion->query(sprintf("CALL USP_validateEmail('%s')", $email));
}
function guardarForm($datos) {
return $this->conexion->query(sprintf("CALL USP_saveForm('%s', '%s', '%s', '%s', '%s', '%s', %d, %d)",
$datos["codigo"],
$datos["nombre"],
$datos["apellidos"],
$datos["email"],
$datos["domicilio"],
$datos["fechanac"],
$datos["pais"],
$datos["ciudad"]
));
}
}
?>
Y el archivo que recibe los datos del formulario e invoca a los métodos de la clase que llaman a los PA es esta:
PHP:
<?php
//Incluimos el archivo de conexión a la Base de datos y nos conectamos
include("conexion.php");
$miConexion = new Cls_Conexion();
//Incluimos el archivo de seguridad de datos
include("seguridad.php");
$desinfectar = new Cls_Desinfeccion();
//Incluimos el archivo de consultas a la Base de datos
include("consultas.php");
$miConsulta = new Cls_Consultas($miConexion->conexion);
//Incluimos el archivo de scripts PHP
include("scripts.php");
$scripts = new Cls_Scripts();
//Código
$codigo = $scripts->codigo();
$verificarCodigo = $miConsulta->codigo($codigo);
if ($verificarCodigo->num_rows) {
do {
$codigo = $scripts->codigo();
$verificarCodigo = $miConsulta->codigo($codigo);
} while ($verificarCodigo = $miConsulta->codigo($codigo));
$verificarCodigo->free();
}
//Nombre
$nombre = (strlen($_POST["nombre"]) && isset($_POST["nombre"]) && !is_null($_POST["nombre"])) ? $scripts->validarNomApe($desinfectar->sanitize($miConexion->conexion, $_POST["nombre"])) : $scripts->formulario();
if (is_null($nombre)) $scripts->formulario("Debe de ingresar su nombre en un formato válido");
//Apellidos
$apellidos = (strlen($_POST["apellidos"]) && isset($_POST["apellidos"]) && !is_null($_POST["apellidos"])) ? $scripts->validarNomApe($desinfectar->sanitize($miConexion->conexion, $_POST["apellidos"])) : $scripts->formulario();
if (is_null($apellidos)) $scripts->formulario("Debe de ingresar sus apellidos en un formato válido");
//E-Mail
$email = (strlen($_POST["email"]) && isset($_POST["email"]) && !is_null($_POST["email"])) ? $scripts->validarEMail($desinfectar->sanitize($miConexion->conexion, $_POST["email"])) : $scripts->formulario();
if (is_null($email))
$scripts->formulario("Debe de ingresar su E-Mail en un formato válido");
else {
$verificarEmail = $miConsulta->email($email);
if ($verificarEmail->num_rows) {
$scripts->formulario("El E-Mail ingresado se encuentra registrado. Por favor, ingrese otro.");
$email = NULL;
$verificarEmail->free();
}
}
//Domicilio
$domicilio = (strlen($_POST["domicilio"]) && isset($_POST["domicilio"]) && !is_null($_POST["domicilio"])) ? $scripts->validarDomicilio($desinfectar->sanitize($miConexion->conexion, $_POST["domicilio"])) : $scripts->formulario();
if (is_null($domicilio)) $scripts->formulario("Debe de ingresar su dirección domiciliaria en un formato válido y utilizando menos de 256 caracteres");
//Fecha de nacimiento
$fechanac = (strlen($_POST["fechanac"]) && isset($_POST["fechanac"]) && !is_null($_POST["fechanac"])) ? $scripts->validarFechNac($desinfectar->sanitize($miConexion->conexion, $_POST["fechanac"])) : $scripts->formulario();
if (is_null($fechanac)) $scripts->formulario("Debe de ingresar la fecha de su nacimiento en un formato válido");
//País
$pais = (strlen($_POST["pais"]) && isset($_POST["pais"]) && !is_null($_POST["pais"])) ? $scripts->validarPaisCiudad($desinfectar->sanitize($miConexion->conexion, $_POST["pais"])) : $scripts->formulario();
if (is_null($pais)) $scripts->formulario("Debe de elegir un país de la lista");
//Ciudad
$ciudad = (strlen($_POST["ciudad"]) && isset($_POST["ciudad"]) && !is_null($_POST["ciudad"])) ? $scripts->validarPaisCiudad($desinfectar->sanitize($miConexion->conexion, $_POST["ciudad"])) : $scripts->formulario();
if (is_null($ciudad)) $scripts->formulario("Debe de elegir una ciudad de la lista");
//Añadimos todos los datos a un array que será enviado a la función de procesamiento de datos
$datos = array(
"codigo" => $codigo,
"nombre" => $nombre,
"apellidos" => $apellidos,
"email" => $email,
"domicilio" => $domicilio,
"fechanac" => $fechanac,
"pais" => $pais,
"ciudad" => $ciudad
);
$bandera = true; //Comodín para determinar si se guardarán o no los datos
foreach ($datos as $dato)
if (is_null($dato)) {
$bandera = false;
break;
}
if ($bandera)
//Guardamos los datos del formulario en la Base de datos
if ($miConsulta->guardarForm($datos))
echo "Los datos han sido guardados satisfactoriamente";
else
echo "Ha ocurrido un error al intentar guardar los datos";
?>
Al parecer, después de la llamada al método codigo, la cual devuelve el resultado esperado, la variable $miConsulta que es la que representa a la clase en el archivo de procesos (el tercero), deja de funcionar, probé imprimiendo mensajes si es que se obtenía un resultado y la respuesta siempre fue negativa, por ejemplo en: echo $miConsulta->email($email) ? "TRUE" : "FALSE"; siempre se imprimía "FALSE", cuando utilizo la función mysqli_errno(), se muestra el código de error 2014 de descripción"Commands out of sync; you can't run this command now", incluso intenté hacer esto:
PHP:
<?php
$paises = $miConsulta->paises();
while ($row = $paises->fetch_array())
echo $row["nombre"] . "<br />";
?>
Se muestra el siguiente mensaje: "Fatal error: Call to a member function fetch_array() on a non-object in line 30", dicha línea es en donde se encuentra el ciclo While.
Como verán en el código, son 3 llamadas a 3 métodos de la clase, la primera llamara al método codigo, la segunda al método email y la tercera al método guardarForm, de las cuales, solamente la primera llamada me retorna el valor esperado, mientras que las otras dos no funcionan, sin embargo, si inhabilito a la primera llamada, es decir, a la del código, funciona la del email pero no la de guardarForm y recién cuando deshabilito la del email, funciona la de guardarForm. Otra forma en que funciona esto es creando una nueva instancia para la conexión y para la clase de esta forma:
PHP:
<?php
//E-Mail
$email = (strlen($_POST["email"]) && isset($_POST["email"]) && !is_null($_POST["email"])) ? $scripts->validarEMail($desinfectar->sanitize($miConexion->conexion, $_POST["email"])) : $scripts->formulario();
if (is_null($email))
$scripts->formulario("Debe de ingresar su E-Mail en un formato válido");
else {
$miConexion2 = new Cls_Conexion();
$miConsulta2 = new Cls_Consultas($miConexion2->conexion);
$verificarEmail = $miConsulta2->email($email);
if ($verificarEmail->num_rows) {
$scripts->formulario("El E-Mail ingresado se encuentra registrado. Por favor, ingrese otro.");
$email = NULL;
$verificarEmail->free();
}
}
//Aquí va el resto del código, no lo volví a poner porque no es necesario
if ($bandera) {
$miConexion3 = new Cls_Conexion();
$miConsulta3 = new Cls_Consultas($miConexion3->conexion);
//Guardamos los datos del formulario en la Base de datos
if ($miConsulta3->guardarForm($datos))
echo "Los datos han sido guardados satisfactoriamente";
else
echo "Ha ocurrido un error al intentar guardar los datos";
}
?>
Del modo mostrado arriba, funciona todo sin necesidad de inhabilitar ninguna llamada. Probé utilizando queries sencillas en lugar de procedimientos almacenados, pero el resultado es el mismo, con lo que todo apunta a que el problema radica en lo que les he explicado.
Cabe señalar que los métodos paises y ciudades, funcionan pues las llamadas que hago para cada uno de esos métodos, las realizo en diferentes archivos, instanciando en cada uno a la conexión y a la clase.
Ahora, mi pregunta es: ¿Por qué solamente puedo utilizar una vez a la variable que instancia a la clase con los métodos y solamente inhabilitando todas menos una, ésta que no es deshabilitada logra funcionar y por qué creando otras instancias para la clase, recién logran funcionar las tres llamadas a los métodos?
Saludos y, de antemano, gracias por su deferencia.