Foros del Web » Programando para Internet » PHP » Frameworks y PHP orientado a objetos »

problema pérdida de recorset al llamar a un objeto

Estas en el tema de problema pérdida de recorset al llamar a un objeto en el foro de Frameworks y PHP orientado a objetos en Foros del Web. Hola a todos y ante todo gracias por anticipado. Resulta que estoy desarrolando una aplicación en PHP, IIS y SQL Server y me ha surgido ...
  #1 (permalink)  
Antiguo 05/09/2005, 04:03
 
Fecha de Ingreso: septiembre-2005
Mensajes: 5
Antigüedad: 18 años, 7 meses
Puntos: 0
Exclamación problema pérdida de recorset al llamar a un objeto

Hola a todos y ante todo gracias por anticipado.

Resulta que estoy desarrolando una aplicación en PHP, IIS y SQL Server y me ha surgido un fallo muy raro que explico a continuación.

Lo primero que hay que aclarar es que la aplicación se empezó a desarrollar con APACHE pero por requisitos del cliente, se desarrolla actualmente en IIS.

El cambio de APACHE a IIS se realizó satisfactoriamente a excepción de ciertos problemas con el código y variables globales que ya están solucionados.

Una vez que las dos aplicaciones (la que trabajaba sobre APACHE se ha dejado como backup) funcionan correctamente, por circustacias se debe instalar la aplicación en un servidor distinto también IIS.

En el nuevo servidor ya estaban instalados el IIS y SQL Server (misma base de datos que el anterior pero en otro servidor). Pues bien se instala PHP con la misma configuración y por arte de magía, existe un problema con un recorset que desaparece y que no ocurre en los dos anteriores servidores.

La verdad es que tuve alguna dificultad para instalar de nuevas el PHP pero y al final para que funcionara, la única diferencia que se observa en el php.ini de los dos servidores IIS, es que en el que funciona está activada la extensión sqlite y en la otra no.

Una vez explicado lo raro del caso, os muestro el código que da error.

function RecogerDatos()
{
$datos = array();
$consulta = " SELECT que me devuelve más de un registro";
$resultado = mssql_query ($consulta);

if ($resultado == 0)
{
echo "Error en la consulta"
exit();
}

if ($resultado!=1)
{
while ($fila=mssql_fetch_array($resultado))
{
$dato_i = new Dato($fila['Id']);
array_push($datos,$dato_i);
}
}
return $datos;
}

Donde se pierde el recorset $resultado es en la primera llamada al constructor Dato (función que realiza una consulta donde con el identificador que he recogido, obtengo datos más concretos de este id).

Bien, otra cosa extraña que un proceso parecido se realiza justo antes a la llamada a esta función y no se pierde el recorset correspondiente.

Como veis todo esto es muy extraño y después de probar a cambiar el código de tal forma que sólo cree un objeto y llamar a un función que me devuelva los datos tantas veces como se necesite (en cuanto creo ese objeto otra vez se pierde), estoy desesperada porque en otra parte de la aplicación se realiza la misma llamada y no pasa nada.

Me podeís dar una idea de cual puede ser el error, si en la base de datos, en la configuración de php, en la llamada al objeto?

Estoy bastante perdida con este error asi que cualquier ayuda es buena, un saludo y si yo puedo ayudar en algo, lo haré

Gracias
  #2 (permalink)  
Antiguo 05/09/2005, 06:09
O_O
 
Fecha de Ingreso: enero-2002
Ubicación: Santiago - Chile
Mensajes: 34.417
Antigüedad: 22 años, 3 meses
Puntos: 129
Y el código de esa clase (Dato) donde está?

De todas formas .. (bueno, habría que ver como ese ese objeto/clase) .. no deberías meter en un bucle como el while() que ahí usas la instancia de tu objeto .. sino, fuera de ese bucle y dentro de tu bucle la llamada al método de tu objeto/clase que corresponda. Incluso ya que eso es una función ... si vas a trabajar con POO (Programación Orientada a objetos) tal vez esa función debería ser a su vez un método de algún otro objeto ..

Un saludo,
  #3 (permalink)  
Antiguo 05/09/2005, 08:05
 
Fecha de Ingreso: septiembre-2005
Mensajes: 5
Antigüedad: 18 años, 7 meses
Puntos: 0
código de la clase dato

Hola Cluster, aqui tienes el constructor del objeto al que se llama en el código anterior.

class Dato{

var $Id='';
var $Nombre='';
var $Poblacion;
var $Direccion;
var $CodigoPostal;
var $Telefono;


//************************************************
// Constructor que contiene los datos //
function Dato($id=false)
{
if ($id)
{
$consulta =" SELECTNombre,";
$consulta .=" Direccion,Poblacion,";
$consulta .= "CodProvi,CodPostal,Telefono,";
$consulta .=" FROM TablaDatos";
$consulta .=" WHERE Id='".$id."'";
$consulta .=" AND FechaHas = '99999999999999'";

$resultado = mssql_query ($consulta);
if ($resultado == 0)
{
echo "ERROR";
exit();
}
$fila = mssql_fetch_array($resultado);

$this->Id = $fila['Id'];
$this->Nombre = $fila[Nombre] ;
$this->Direccion = $fila['Direccion'] ;
$this->Poblacion = $fila['Poblacion'] ;
$this->CodigoPostal = $fila['CodPostal'] ;
$this->Telefono = $fila['Telefono'] ;
}
}
}

Respecto a lo que me dices que poner en un método ya lo hice, es decir en vez de llamar a este constructor en el while, llamaba a un método que hacía exactamente lo que hace éste (vamos un copy-paste). El resultado es que al realizar la segunda llamada a este método se pierde el recorset otra vez.

A ver si se te ocurre algo viendo este código. Muchas gracias por tu ayuda.
  #4 (permalink)  
Antiguo 05/09/2005, 10:29
O_O
 
Fecha de Ingreso: enero-2002
Ubicación: Santiago - Chile
Mensajes: 34.417
Antigüedad: 22 años, 3 meses
Puntos: 129
Realmente no entiendo que es lo que quieres hacer ...

Esa otra función que llamas RecogerDatos() creo que debería formar parte de tu objeto "Dato" y ahí llamar al método que corresponda para lo que requieras.

Bajo esta premisa tu tendrías algo tipo:

Código PHP:
<?
include ("tu_clase.php");
$tu_instancia = new Dato();
$tu_instancia->Dato();
$datos_en_array=$tu_instancia->RecogerDatos(); // o bien esto un método privado de tu classe primaria.
// Un uso de lo que te devolvió un método .. o bien incluso otro método en tu objeto que te dé el formato de salida de tus datos ...
foreach ($datos_en_array as $dato){
   echo 
$dato."<br>";
}
?>
Y tu método "RegogerDatos()" (si lo incrustras en tu objeto "Dato") sería algo tipo:
$dato_i = $this->Dato($fila['Id']);
array_push($datos,$dato_i);

o similar ... llamando a tu método "Dato" no a la Classe (podrías diferenciar más el tema usando nombres diferentes para tu classe y sus métodos).

Por otro lado .. $fila = mssql_fetch_array($resultado); si lo quieres en un objeto pues luego haces $this-> ... podrías usar mssql_fetch_objetc() ...

Un saludo,
  #5 (permalink)  
Antiguo 06/09/2005, 07:47
 
Fecha de Ingreso: septiembre-2005
Mensajes: 5
Antigüedad: 18 años, 7 meses
Puntos: 0
Hola de nuevo y gracias por tu ayuda.

Te explico una cosa antes de seguir, resulta que esta aplicación yo no la he desarrollado sino que me la he encontrado así y tengo que arreglar todos los errores que aparezcan, adaptarla al IIS (estaba en APACHE) y en un futuro seguir desarrollando cosas nuevas.

Dejando este punto a un lado, cualquier cambio puede afectar a otras zonas de la aplicación y como tú bien me has comentado, no veía lógico meter el new en el while asi que también pensé en lo del método.

Para que no interfiriera en el resto de la aplicación, dejé tal y como te he mostrado el constructor:

// Constructor que contiene los datos //
function Dato($id=false)
{
if ($id)
{
$consulta =" SELECTNombre,";
$consulta .=" Direccion,Poblacion,";
$consulta .= "CodProvi,CodPostal,Telefono,";
$consulta .=" FROM TablaDatos";
$consulta .=" WHERE Id='".$id."'";
$consulta .=" AND FechaHas = '99999999999999'";

$resultado = mssql_query ($consulta);
if ($resultado == 0)
{
echo "ERROR";
exit();
}
$fila = mssql_fetch_array($resultado);

$this->Id = $fila['Id'];
$this->Nombre = $fila[Nombre] ;
$this->Direccion = $fila['Direccion'] ;
$this->Poblacion = $fila['Poblacion'] ;
$this->CodigoPostal = $fila['CodPostal'] ;
$this->Telefono = $fila['Telefono'] ;
}
}
}

y me cree el siguiente método:

function getDatos($id)
{
$consulta =" SELECTNombre,";
$consulta .=" Direccion,Poblacion,";
$consulta .= "CodProvi,CodPostal,Telefono,";
$consulta .=" FROM TablaDatos";
$consulta .=" WHERE Id='".$id."'";
$consulta .=" AND FechaHas = '99999999999999'";

$resultado = mssql_query ($consulta);
if ($resultado == 0)
{
echo "ERROR";
exit();
}
$fila = mssql_fetch_array($resultado);

$this->Id = $fila['Id'];
$this->Nombre = $fila[Nombre] ;
$this->Direccion = $fila['Direccion'] ;
$this->Poblacion = $fila['Poblacion'] ;
$this->CodigoPostal = $fila['CodPostal'] ;
$this->Telefono = $fila['Telefono'] ;

return $this;
}

Con este nuevo método, la otra función quedaba así:

function RecogerDatos()
{
$datos = array();
$consulta = " SELECT que me devuelve más de un registro";
$resultado = mssql_query ($consulta);

if ($resultado == 0)
{
echo "Error en la consulta"
exit();
}

if ($resultado!=1)
{
$dato_i = new Dato(); <-- al no pasarle argumento, no id=false por lo que no se mete en la consulta
while ($fila=mssql_fetch_array($resultado))
{
array_push($datos,$dato_i->getDatos($fila['Id']));
}
}
return $datos;
}

Creo que esto se ajusta a lo que me comentas en tu contestación. Pues bien, cuando ejecuté este código el recorset seguía perdiéndose en la segunda pasada del while. De hecho con un único registro no hay problema porque este y el otro código no da errores.

Todas estas cosas extrañas son lo aun más porque en otro servidor la misma aplicación, es decir el primer código del principio funciona correctamente y no se pierde el recorset en ningún momento.

A ver si con tu ayuda puedo arreglar esto en este servidor concreto porque la verdad es que estoy ya un poco desesperada.

Un Saludo y gracias de nuevo
  #6 (permalink)  
Antiguo 06/09/2005, 13:44
O_O
 
Fecha de Ingreso: enero-2002
Ubicación: Santiago - Chile
Mensajes: 34.417
Antigüedad: 22 años, 3 meses
Puntos: 129
Realmente (me vas a tener que disculpar) no entiendo como funciona todo el sistema (parte importante para llegar a ver por qué se puede comportar de esa forma). Sigue insistiendo en este mensaje a ver si alguien te puede orientar al respecto. Intenta adjuntar la mayor parte de código que uses .. tanto de tus objetos como los scripts donde lo uses para tener alguna noción más global de como lo estás usando.

Un saludo,
  #7 (permalink)  
Antiguo 07/09/2005, 01:23
 
Fecha de Ingreso: septiembre-2005
Mensajes: 5
Antigüedad: 18 años, 7 meses
Puntos: 0
Intento aclarar sentido del código

Hola de nuevo:

Voy a intentar explicar el sentido de estas 2 funciones que he mostrado:

1.- Tengo una clase Dato que como atributos tiene todos los datos personales de las personas en la base de datos y todos los métodos que tiene, nos dan unos u otros datos según necesitemos, en unas u otras condiciones.

2.- La función Recoger datos, obtiene el identificador de todas las personas de la base de datos que cumplen una condición y después por cada uno de estos identificadores construye un array de objetos. Cada objeto contiene todos los datos personales de la persona correspondiente.

Con esto, una vez tengo el recorset con todos los identificadores (éste es el que se pierde en la segunda pasada del while), lo que hacen es crear una instancia por cada identificador y "llenarla" con todos sus datos personales para incluirlo en el array.

Después en otra fase, con este array de objetos se hacen varias cosas como mostrar por pantalla algunos de ellos, usarlos como dato de comparación etc... Pero esto no es caso de estudio porque no falla y lo hace bien.

Creo que con esta explicación ya se puede tener una idea de que sentido tienen estas dos funciones.

De todas formas, tal y como bien dijiste el sistema utilizado de crear una instancia por cada identificador no es muy bueno pero en los otros dos servidores donde está funcionando el sistema, funciona correctamente y en el nuevo servidor es donde de repente se pierde el recorset.

Como tenía que arreglar este error, que en este caso concreto no me permite ver todos los nombres de las personas (sólo veo el primero). Cambié el código para estas dos funciones y así no afectar al resto de la aplicación, para crear una única instancia y llamar únicamente al nuevo método en el bucle while.

Aun con este cambio, la pérdida del recorset perdura y sólo puedo ver el primer nombre de todos los identificadores que tengo.

No se si al final he podido dejar más claro el problema que tengo, pero insisto en que la pérdida del recorset se produce únicamente en uno de los 3 servidores en los que actualmente está instalada la aplicación y eso es lo que me tiene muy mosqueada.

Ya no me extiendo más, un saludo y de nuevo gracias por la ayuda prestada.
  #8 (permalink)  
Antiguo 30/09/2005, 17:32
 
Fecha de Ingreso: septiembre-2005
Mensajes: 30
Antigüedad: 18 años, 7 meses
Puntos: 0
Una propuesta

Hola :

Bueno, aqui pudieras resolver realizando JOIN para no tener que hacer una reconsulta dentro del constructor.

La idea es que si vas a seleccionar un valor ( v1 ) para luego seleccionar otro conjunto de valores(v2) segun cada ( v1 ) pudieras hacer todo en una sola consulta y luego crear todos los objs que quieras.

Digamos, asi lo tienes:

SELECT * from T1 -> Lista de v1
Por cada V1:
SELECT * from T2 -> Lista de v2 para un determinado v1

Asi queda mas eficiente la consulta y no tienes que realizar reconsultas:
SELECT * from T1,T2 WHERE T1.campodev1=T2.campodev1

Y tendras una lista de recordset de la siguiente manera:
v1 1,v2 1
v1 1, v2 2
...
v1 1, v2 N -->Segun la cantidad de valores de T2 que contienen v1 1

Y asi por cada valor de v1

Al no realizar reconsultas no tendras que volver a crear recordsets que probablemte sea la causa por la que lo pierdes ( fijate que es en el primer ciclo ).

Ademas, la consulta que tu haces es menos eficiente porque estas haciendo v1 consultas en la tabla T2 y de la forma que te digo solo estas haciendo 1 consulta.

Saludos
__________________
Alojamiento Web - Alojamiento web y Servidores dedicados. Servidores en USA y Londres.
Hosting,PHP,Java,CSS,SEO BLOG - Web Hosting, Posicionamiento Web, Programacion en PHP, Java, CSS y mucho mas.
  #9 (permalink)  
Antiguo 17/10/2005, 11:02
Avatar de moron  
Fecha de Ingreso: mayo-2004
Mensajes: 972
Antigüedad: 20 años
Puntos: 2
$consulta =" SELECTNombre,";

no debería ser $consulta =" SELECT Nombre,";

digo, de pronto... me parece..
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 06:52.