Foros del Web » Programando para Internet » PHP »

Recursividad en PHP

Estas en el tema de Recursividad en PHP en el foro de PHP en Foros del Web. Hola a [email protected], tras echar un largo vistazo rápido por encima a los temas abiertos hasta el momento, no he encontrado nada sobre un tema ...
  #1 (permalink)  
Antiguo 07/04/2005, 07:17
 
Fecha de Ingreso: abril-2005
Mensajes: 16
Antigüedad: 12 años, 8 meses
Puntos: 0
Pregunta Recursividad en PHP

Hola a [email protected],

tras echar un largo vistazo rápido por encima a los temas abiertos hasta el momento, no he encontrado nada sobre un tema que me está volviendo loco. Tranquilos que no voy a mandaros el código fuente para no desquiciaros.

Mi pregunta es muy sencilla: ¿Tiene PHP algún tipo de problema con la recursividad? ¿Cómo hay que declarar los parámetros de una función o bien sus variables locales? Si quereis que sea más concreto, se trata de la forma en que las variables en una función recursiva en PHP toma (más bien, pierden) valores en cada llamada recursiva. La recursividad suele ser en algunas ocasiones una solución más elegante y sencilla que hacerlo iterativamente, pero llevo ya dos semanas con una función, y no consigo entender por qué no termina de funcionar. ¿A alguno de vosotros le ha pasado lo mismo? Si es así, ¿podeis decirme cómo lo solucionasteis?

Muchísimas gracias a todo el que se tome la molestia de contestar.

Un saludo!!
  #2 (permalink)  
Antiguo 07/04/2005, 08:15
 
Fecha de Ingreso: marzo-2005
Mensajes: 163
Antigüedad: 12 años, 9 meses
Puntos: 0
Por mas que nos desquicies con tu codigo seria bueno mirarlo. Por lo poco que he heco recursivo trabaja como la mayoria de los lenguajes. He utilizado variables por referencia y por copia valor. Igualmente un poco de codigo vendria bien para mirar en detalle tu problema.
Saludos
  #3 (permalink)  
Antiguo 07/04/2005, 08:18
Avatar de nicolaspar  
Fecha de Ingreso: noviembre-2004
Ubicación: Villa Ballester Bs-As|Ar
Mensajes: 2.002
Antigüedad: 13 años
Puntos: 34
la verdad que no. Igual, si por ejemplo se pasar la conexion a la db se trata, no la crees dentro de la función, sino que pasála como referencia. Esto a modo de ejemplo que pasa con algunos valores, como también hay otros que deben ser declarados como globales.

Pone le código de tu función, la manera en que la llamas, y contanos el cometido que esta tiene.
__________________
Mi punto de partida es Que Bueno Lo Nuevo
  #4 (permalink)  
Antiguo 07/04/2005, 09:51
 
Fecha de Ingreso: octubre-2004
Ubicación: En algún lugar de la República Oriental del Uruguay
Mensajes: 366
Antigüedad: 13 años, 1 mes
Puntos: 0
yo tengo una función recursiva que crea categorías y sus subcategorías a partir de dos tablas, si queres te la posteo para que la veas y te sirva como referencia.
  #5 (permalink)  
Antiguo 07/04/2005, 10:40
O_O
 
Fecha de Ingreso: enero-2002
Ubicación: Santiago - Chile
Mensajes: 34.417
Antigüedad: 15 años, 11 meses
Puntos: 126
ratamaster
Te refieres a esto tuyo? .. (o algo incluso mejorado?)
http://www.forosdelweb.com/f18/recursividad-280857/

Un saludo,
  #6 (permalink)  
Antiguo 08/04/2005, 02:27
 
Fecha de Ingreso: abril-2005
Mensajes: 16
Antigüedad: 12 años, 8 meses
Puntos: 0
Antes de nada, muchísimas gracias a todos por la rapidez de respuesta!!

Por desgracia, no las he visto hasta hoy! :(

Antes de mandaros el código, y explicaron por encima la estructura de tablas que tengo en la BD (que son bastantes líneas, y por eso no las quería poner aquí), os doy algunos detalles, y una pequeña explicación, OK?

Para empezar yo no utilizo MySQL, sino Oracle 9i. La función recursiva en cuestión está muy ligada a esto de los foros, y es que se trata de que muestre los títulos de las intervenciones en un foro (hecho "a pelo") en forma de árbol de directorios, de modo que hay una intervención inicial sobre un tema y 'n' respuestas a esa intervención o a otras intervenciones hijas de esa intervención, o hijas de hijas... No sé si me he explicado bien, me entendeis?

De manera que en el programa principal me conecto con la base de datos, y llamo a un primer procedimiento que extrae esa primera intervención inicial de una tabla de la BD que contiene SÓLO la intervenciones iniciales, y la pinta por pantalla como raíz del árbol:
function ConstruirArbol($bd, $NombreTema)
Y dentro de esta función llamo a la función recursiva propiamente dicha:
function PintarHijos($bd, $ID_Intervencion_Inicial)
Esta función intenta extraer los hijos de la intervención que se le pasa como parámetro (en caso de que los tuviera), y si los tiene, se va llamando recursivamente mientras haya intervenciones hijas que recuperar:
PintarHijos($bd, $ID_Intervencion_Hija);

Creeis que puede ser un problema de pasar las variables por referencia??

Muchísimas gracias de nuevo!!

Un saludo!!
  #7 (permalink)  
Antiguo 08/04/2005, 07:16
Avatar de nicolaspar  
Fecha de Ingreso: noviembre-2004
Ubicación: Villa Ballester Bs-As|Ar
Mensajes: 2.002
Antigüedad: 13 años
Puntos: 34
Yo he hecho algo parecido, en mi caso se trataba de dibujar un arbol al estilo dirs de windows, con carpetas y archivos. Lo que tenia era una sola funcion, con dos lineas adentro, la misma recibia el padre (quien inicialmente era 0, la raiz), y iba dibujando recursivamente sus hijos. Te digo esto, por que no se si sea necesario dos funciones como lo estas haciendo, aunque tal vez en tu caso si...

Cualquier cosa, postea tus funciones a ver si vemos algo raro.
__________________
Mi punto de partida es Que Bueno Lo Nuevo
  #8 (permalink)  
Antiguo 08/04/2005, 08:20
 
Fecha de Ingreso: octubre-2004
Ubicación: En algún lugar de la República Oriental del Uruguay
Mensajes: 366
Antigüedad: 13 años, 1 mes
Puntos: 0
Cluster, tiene unas modificaciones y me parece más clara, lo que hice yo es crear todo un árbol, en un principio (cuando la página se carga), se despliegan solo las categorías de nivel 0, y si las cliqueo, de van desplegando sus subcategorías, es una mezcla de php con javascript. Aquí posteo algo muy sencillo para tomar como referencia, las tablas las pueden ver en el link que posteó Cluster en este tema. NaughtyFer, que tu motor de bd sea oracle en este caso no importa, ya que la query es compatible con oracle (como se sabe mucho más completo que mysql, jeje, es lo que se de oído).

Código PHP:
function display_categories($parent,$level) {
$sql="SELECT categories.CatId, categories.CatParentId,catlang.CatLangName FROM categories
INNER JOIN catlang ON categories.CatId = catlang.CatId
WHERE LangId=1 AND categories.CatParentId ='"
.$parent."'";

$result mysql_query($sql)or die("6 ".mysql_error());
While(
$row=mysql_fetch_array($result)) {
     if(
$row['CatParentId']>0){
       print 
"$level>>";
       }
       print 
" $row[CatLangName]<br>";
       
display_categories($row['CatId'], $row['CatLangName']);
    }
}
display_categories('',0); 


Ratamaster
  #9 (permalink)  
Antiguo 08/04/2005, 13:32
 
Fecha de Ingreso: abril-2005
Mensajes: 16
Antigüedad: 12 años, 8 meses
Puntos: 0
Nicolaspar, con SÓLO dos líneas lo conseguiste????

Cómo has conseguido hacerlo con tan poquitas líneas? Porque lo que pretendo es justamente lo que comentas: crear un árbol de intervenciones con la apariencia de los árboles de directorios de Windows.

Me puedes contar por encima qué estructura de tablas tienes, y qué cómo funciona el procedimiento?

Por cierto, no sé si esto será relevante, pero unas vez en pantalla, los títulos de las intervenciones en los foros son hipervínculos <A href=...> a un marco en la misma ventana, donde aparece el texto perteneciente a la intervención, pero vamos, que eso no interfiere en la función recursiva.

Una vez más, mil gracias a todos! Saludos!!
  #10 (permalink)  
Antiguo 08/04/2005, 13:48
Avatar de nicolaspar  
Fecha de Ingreso: noviembre-2004
Ubicación: Villa Ballester Bs-As|Ar
Mensajes: 2.002
Antigüedad: 13 años
Puntos: 34
No tengo en este momento el codigo, pero a la noche te lo publico acompañado de una camtura para que veas el resultado.


PD: Dos lineas es una forma de decir. La funcion recursiva tendrá unas 6 lineas, pero despues esta el js que dibuja el tree es una clase, el html y demás...
Depsues es una sola tabla con 5 campos (creo, no recuerdo bien, hace unos meses largo que lo he hecho).
__________________
Mi punto de partida es Que Bueno Lo Nuevo

Última edición por nicolaspar; 08/04/2005 a las 13:50
  #11 (permalink)  
Antiguo 08/04/2005, 13:56
 
Fecha de Ingreso: abril-2005
Mensajes: 16
Antigüedad: 12 años, 8 meses
Puntos: 0
Ah! Una última cosa, que se me ha olvidado preguntaros antes. Ratamaster, ya le eché un ojo al link con la función que Cluster me sugirió (http://www.forosdelweb.com/showthread.php?t=280857), y la función, a grandes rasgos se parece mucho a la que trato de hacer, salvando las diferencias de sintaxis entre las funciones de PHP para MySQL y para Oracle 9i. Pero os quería preguntar algo: habeis oído hablar de problemas con la función ora_fetch()?? Es que, ahora mismo, lo que trato de hacer es acotar el problema, y una de las posibilidades por las que no funciona podría ser por la forma en que ora_fetch() trata las filas NULAS recuperadas (ya sabeis; puesto que hay un while, llegará un momento en que intente recuperar una fila que no contenga nada). A alguno de vosotros le ha pasado, o sabe de alguien que haya tenido problemas para recuperar datos con ora_fetch()?

Gracias por seguir aportando ideas. Me estais ayudando mucho!! ;D
  #12 (permalink)  
Antiguo 08/04/2005, 14:01
 
Fecha de Ingreso: abril-2005
Mensajes: 16
Antigüedad: 12 años, 8 meses
Puntos: 0
Gracias nicolaspar!

Aunque tengo el código "grabado a fuego" en la cabeza por los quebraderos de cabeza que me está dando, yo tampoco lo tengo ahora mismo donde estoy. Mañana postearé las funciones para que me digas si ves algo raro. De todas formas, tampoco pretendo que te rompas la cabeza; si ves algo mal que salta a la vista, perfecto. Pero tampoco quiero que pierdas tu tiempo, OK?

Gracias por tomarte la molestia! Ciao!
  #13 (permalink)  
Antiguo 08/04/2005, 14:13
Avatar de nicolaspar  
Fecha de Ingreso: noviembre-2004
Ubicación: Villa Ballester Bs-As|Ar
Mensajes: 2.002
Antigüedad: 13 años
Puntos: 34
Cita:
Iniciado por NaughtyFer
Gracias nicolaspar!

Aunque tengo el código "grabado a fuego" en la cabeza por los quebraderos de cabeza que me está dando, yo tampoco lo tengo ahora mismo donde estoy. Mañana postearé las funciones para que me digas si ves algo raro. De todas formas, tampoco pretendo que te rompas la cabeza; si ves algo mal que salta a la vista, perfecto. Pero tampoco quiero que pierdas tu tiempo, OK?

Gracias por tomarte la molestia! Ciao!
No hay problema neughtyfer (que nick !! ), yo hoy te pondré la funcion que use y la estructura de la db.
Y todo bien, no es molestia ayudar a gente con ganas de aprender y buenas intenciones!
__________________
Mi punto de partida es Que Bueno Lo Nuevo
  #14 (permalink)  
Antiguo 08/04/2005, 16:48
O_O
 
Fecha de Ingreso: enero-2002
Ubicación: Santiago - Chile
Mensajes: 34.417
Antigüedad: 15 años, 11 meses
Puntos: 126
Si, .. ese es el principio de la recursividad .. "se llama a si mismo" (la función que ahí define) ..

Un saludo,
  #15 (permalink)  
Antiguo 08/04/2005, 19:34
Avatar de nicolaspar  
Fecha de Ingreso: noviembre-2004
Ubicación: Villa Ballester Bs-As|Ar
Mensajes: 2.002
Antigüedad: 13 años
Puntos: 34
Acá lo prometido:
La función php es la siguiente:

Código PHP:
function arbol(&$conexion,$inicio,$pais,$idioma){
 
$str ='';
 
$aux=mysql_query("select s.codigo, s.padre, s.nombre from secciones s where padre ='".$inicio."' and idioma = '".$idioma."' and pais = '".$pais."' and estado =1",$conexion);
 while(
$r=mysql_fetch_row($aux)){
 
$str .= "d.add(".$r[0].",".$r[1].",'".$r[2]."','secciones_modificar.php?padre=".$r[1]."','secciones_modificar.php?codigo=".$r[0]."','secciones_borrar.php?codigo=".$r[0]."');\n";
    
$str .=arbol($conexion,$r[0],$pais,$idioma); 
 }
 
mysql_free_result($aux);
 return 
$str;

Luego, incluis la conexión a la db y llamas a la funcion:

Código PHP:
<script type="text/javascript">
d = new dTree('d');
d.add(0,-1,'Secciones');
<?php  if(arbol($conexion,0,0,0)==''){#Esto nunca me gusto mucho?>
        document.write(d);
<?php  
        
echo 'document.write("<a href=paginaCreaSeccion.php>Nueva Seccion.</a><br>&nbsp;<br>");';
      }else{
        echo 
arbol($conexion,0,0,0);
  
?>
        document.write(d);
<?php}?>
</script>
Ahora la db es la siguiente en mi caso:

Cita:
CREATE TABLE `secciones` (
`codigo` int(10) unsigned NOT NULL auto_increment,
`nombre` varchar(255) default NULL,
`idioma` int(10) unsigned default '0',
`pais` int(10) unsigned default '0',
`padre` int(10) unsigned default '0',
`template` int(10) unsigned default '0',
`nav` tinyint(1) default '0',
`header` tinyint(1) default '0',
`footer` tinyint(1) default '0',
`popup` tinyint(1) default '0',
`contenido` tinyint(1) default '0',
`orden` int(10) default '0',
`estado` tinyint(1) default '1',
PRIMARY KEY (`codigo`)
) TYPE=MyISAM;
Obviamente, como verás, hay campos que son especificos de mi caso, y que no usaras, como template, idioma, país, header, etc...lo unico qu ete interesa es el codigo y el padre en si.
Luego, la función va llamando a un objeto en js, para el cual he usado el del sitio: http://www.destroydrop.com/javascripts/tree/ y he adaptado a mis necesidades.
Este es una captura del resultado final:http://estudiowas.com.ar/images/forosdelweb.gif

tambien podes usar otros tree como ser:
http://www.treemenu.net/treemenu/3fr_beenthere.html

Espero te sirva de algo esto.
PD: lastima que es algo que nunca pude terminar
__________________
Mi punto de partida es Que Bueno Lo Nuevo
  #16 (permalink)  
Antiguo 09/04/2005, 03:15
 
Fecha de Ingreso: abril-2005
Mensajes: 16
Antigüedad: 12 años, 8 meses
Puntos: 0
Gracias de nuevo nicolaspar!

Enseguida probé lo de pasar el manejador de la BD por referencia, pero me temo que no debe ser ese el problema. Antes de poner el código, os cuento algunas cosas:
- Intento evitar en la medida de lo posible usar Javascript, y que los scripts de PHP sean "puros" de PHP.
- No sé si estais familiarizados con el modelo ER de las bases de datos. Os digo esto porque lo que tengo la estructura de tablas que tengo es una una doble jerarquía, donde la tabla padre es INTERVENCION_EN_FORO. De ella "cuelgan" dos tablas hijas: PUBLICA y PRIVADA (esta última es irrelevante). Y de la tabla PUBLICA "cuelgan" dos tablas hijas: INICIAL y REPLICA.

Aquí os pongo la estructura de las 3 tablas que intervienen (es PL/SQL bajo Oracle 9i):
CREATE TABLE INTERVENCION_EN_FORO (
ID_Int NUMBER(10) NOT NULL,
NIA NUMBER(9) NOT NULL
CHECK (NIA BETWEEN 100000000 AND 100099999),
Titulo_intervencion VARCHAR2(100) NOT NULL,
Texto_intervencion VARCHAR2(2000) NOT NULL,
Tipo_intervencion CHAR(7) NOT NULL
CHECK (Tipo_intervencion IN ('PUBLICA','PRIVADA')),
Titulo_tema VARCHAR2(100) NOT NULL,
Fecha_intervenc VARCHAR2(10) NOT NULL,
Hora_intervenc VARCHAR2(5) NOT NULL,
PRIMARY KEY (ID_Int),
FOREIGN KEY (NIA) REFERENCES USUARIO ON DELETE CASCADE
);

CREATE TABLE PUBLICA (
ID_Int NUMBER(10) NOT NULL,
NIA NUMBER(9) NOT NULL
CHECK (NIA BETWEEN 100000000 AND 100099999),
Titulo_intervencion VARCHAR2(100) NOT NULL,
Tipo_Int_Publica CHAR(7) NOT NULL
CHECK (Tipo_Int_Publica IN ('INICIAL', 'REPLICA')),
PRIMARY KEY (ID_Int),
FOREIGN KEY (ID_Int) REFERENCES INTERVENCION_EN_FORO ON DELETE CASCADE
);

CREATE TABLE INICIAL (
ID_Int NUMBER(10) NOT NULL,
NIA NUMBER(9) NOT NULL
CHECK (NIA BETWEEN 100000000 AND 100099999),
Titulo_intervencion VARCHAR2(100) NOT NULL,
PRIMARY KEY (ID_Int),
FOREIGN KEY (ID_Int) REFERENCES PUBLICA ON DELETE CASCADE
);

CREATE TABLE REPLICA (
ID_Int NUMBER(10) NOT NULL,
NIA NUMBER(9) NOT NULL
CHECK (NIA BETWEEN 100000000 AND 100099999),
Titulo_intervencion VARCHAR2(100) NOT NULL,
ID_Int_precede NUMBER(10) NOT NULL,
PRIMARY KEY (ID_Int),
FOREIGN KEY (ID_Int) REFERENCES PUBLICA ON DELETE CASCADE,
FOREIGN KEY (ID_Int_precede) REFERENCES PUBLICA ON DELETE CASCADE
);
  #17 (permalink)  
Antiguo 09/04/2005, 03:31
 
Fecha de Ingreso: abril-2005
Mensajes: 16
Antigüedad: 12 años, 8 meses
Puntos: 0
Como veis la estructura de las tablas es muy simple, y con muy poquitos campos. Por cierto, el ID_Int (Identificador de la intervencion, es un entero autoincrementable, OK?)

Y ahí os van las famosas dos funciones, y las primeras líneas del programa principal. A ver si veis algo raro!

function ConstruirArbol($bd, $NombreTema)
{
$sql = "SELECT ID_Int, Titulo_intervencion FROM INICIAL NATURAL JOIN INTERVENCION_EN_FORO WHERE Titulo_tema = :NombreTema";
ora_parse($bd, $sql, 0);
ora_bind($bd, "NombreTema", ":NombreTema", 128, 1);
ora_exec($bd);
if (ora_fetch($bd))
{
$ID = trim(ora_getcolumn($bd, 0));
$TituloIntPadre = trim(ora_getcolumn($bd, 1));
if ($TituloIntPadre != NULL)
{
print("<A HREF=Pag_3C-Dcho-Abajo.php?TituloIntervencionPadre=".urlencode($Tit uloIntPadre)."&ID_Int_Padre=$ID Target=Marco3C-DchoInf>$TituloIntPadre</A>");
$prefijo = "&nbsp;&nbsp;|---";
PintarHijos($bd, $ID, $prefijo);
}
}
}
/////////////////////////////////////////////////////////////////////////////////////////////
function PintarHijos(&$bd, $ID_Intervencion, $pref)
{
global $ID;
$ID = $ID_Intervencion;
$sql2 = "SELECT ID_Int, Titulo_Intervencion FROM REPLICA WHERE (ID_Int_precede = :ID)";
ora_parse($bd, $sql2, 0);
ora_bind($bd, "ID", ":ID", 10, 1);
ora_exec($bd);
ora_fetch($bd);
if (ora_numrows($bd) != 0)
{
$ID_Int_Replica = trim(ora_getcolumn($bd, 0));
$Titulo_Int_Replica = trim(ora_getcolumn($bd, 1));
print("<BR>".$pref."<A HREF=Pag_3C-Dcho-Abajo.php?TituloIntervencionPadre=".urlencode($Tit ulo_Int_Replica)."&ID_Int_Padre=$ID_Int_Replica Target=Marco3C-DchoInf> $Titulo_Int_Replica </A>");
PintarHijos($bd, $ID_Int_Replica, $pref."&nbsp;&nbsp;|---");
}
}
///////////////////////////////////////////////////////////////////////////////////////////////

Y el script comienza así:
<?php
if (isset($_GET['NombreTema']))
{
$NombreTema = $_GET['NombreTema'];
print("<BR><p ALIGN=CENTER><b><u><i><font size=5 color=#FFCC66>Tema del Foro : $NombreTema</font></i></u> </b></p>");
require("Conectar_a_BD.php");
if ($conexion)
{
$bd = ora_open($conexion);
$num_interv = ConstruirArbol($bd, $NombreTema);
...........
...........
}
?>

A tener en cuenta:
- Al pinchar sobre el título de la intervención, que es un hipervínculo, se muestra en un marco inferior (en la misma página) el texto asociado a esa intervención.
- Ora_numrows, NO devuelve el número total de filas recuperadas, sino el identificador de cada fila (el rownum).
- Declaré $ID como global porque de no hacerlo así, me daba problemas el comando ora_exec.
- Cuando escribo: require("Conectar_a_BD.php"); en realidad estoy llamando a dos líneas de código que hacen: $conexion = ora_logon(User, PW);

Siento que sea tanto código. Por esto era tan reacio a escribirlo todo, e intentaba explicaroslo con palabras o pseudocódigo.

Bueno, pues si veis alguna burrada que yo no haya visto, comentádmelo por favor.

Muchísimas gracias! Hasta el próximo!!
  #18 (permalink)  
Antiguo 09/04/2005, 09:14
Avatar de nicolaspar  
Fecha de Ingreso: noviembre-2004
Ubicación: Villa Ballester Bs-As|Ar
Mensajes: 2.002
Antigüedad: 13 años
Puntos: 34
A todo esto...cual es el problema puntual que tenes? por que creo no no lo has dicho...o si?

PD: Yo llevaría todo a una sola funcion, en una sola consulta...puede que haya quilombillos por ese tema.
__________________
Mi punto de partida es Que Bueno Lo Nuevo
  #19 (permalink)  
Antiguo 09/04/2005, 12:53
 
Fecha de Ingreso: abril-2005
Mensajes: 16
Antigüedad: 12 años, 8 meses
Puntos: 0
Hola de nuevo!! ;D Sí, el problema que tengo os lo comentaba en el primer mensaje que posteé. Os preguntaba por encima si sabíais si PHP tenía algún problema con las funciones recursivas, o con las variables (tanto los parámetros de la función, como las variables locales a la función), y cómo habría que declararlas.

Ahora que ya os he mandado el código, os diré que, a base de poner printouts de las variables importantes "en sitios estratégicos" (simplemente a continuación de la llamada recursiva), he visto que, en realidad, SÍ que se van recuperando las llamadas recursivas, pero los títulos de la intervenciones no se pintan por pantalla (porque no se recuperan de la BD), aunque SÍ los grupos de caracteres "|--" que le paso a la función.

De cualquiero modo, por lo pronto voy a probar a hacer lo que me comentas de sacar el código de la funcion 'ConstruirArbol(....)' al programa principal, y dejar sólo la función recursiva 'PintarHijos', a ver qué pasa.

Como siempre, mil gracias por seguir aportando ideas!!

Un saludo, y buen finde!!

P.D.: Una última cosa, es que me ha hecho gracia la palabra, y no sé lo que quiere decir (es una palabra argentina?). Qué significa quilombillo, nicolaspar?

Última edición por NaughtyFer; 09/04/2005 a las 12:56 Razón: Olvidé preguntar una cosa
  #20 (permalink)  
Antiguo 09/04/2005, 13:56
Avatar de nicolaspar  
Fecha de Ingreso: noviembre-2004
Ubicación: Villa Ballester Bs-As|Ar
Mensajes: 2.002
Antigüedad: 13 años
Puntos: 34
Ok, no problem, cualquier error dilo.
Jaja...no se si sea una palabra regional, es mas, no lo creo. La palabra fue "flandeada" (esa si la acabo de inventar, y viene de flanders:p), y proviene de Quilombo, que eran los lugares (tal vez lo sean todavía!!¿¿???) donde habia un prostibulo, y por los "problemas" que se armaban en estos, los llamaban asi. O sea, quiere decir problema, enrredo, o como sea...:p
Según http://www.diccionarios.com, es una palabra argentina / uruguaya .(
__________________
Mi punto de partida es Que Bueno Lo Nuevo
  #21 (permalink)  
Antiguo 11/04/2005, 03:16
 
Fecha de Ingreso: abril-2005
Mensajes: 16
Antigüedad: 12 años, 8 meses
Puntos: 0
Hola de nuevo!!!

Me temo que no traigo buenas noticias. Después de despejar por un día la cabeza, y volver con fuerzas renovadas, me temos que seguimos en el mismo punto. :(

Ahora ya sólo tengo una función (la función recursiva), aunque la he cambiado ligeramente, sigue sin funcionar.

El código que antes estaba en la función ConstruirArbol($bd, $NombreTema), ahora ya está incorporado al script justo a continuación de la línea: $bd = ora_open($conexion);

De tal modo que ahora se llama a PintarHijos($bd, $ID, $pref); desde el código principal, y la función ha quedado así:

50 function PintarHijos($bd, $ID_Intervencion, $pref)
51 {
52 global $ID;
53
54 $ID = $ID_Intervencion;
55 $sql2 = "SELECT ID_Int, Titulo_Intervencion FROM REPLICA WHERE (ID_Int_precede = :ID)";
56 ora_parse($bd, $sql2, 0);
57 ora_bind($bd, "ID", ":ID", 10, 1);
58 ora_exec($bd);
59 while (ora_fetch($bd))
60 {
61 $ID_Int_Replica = trim(ora_getcolumn($bd, 0));
62 $Titulo_Int_Replica = trim(ora_getcolumn($bd, 1));
63 print("<BR>".$pref."<A HREF=Pag_3C-Dcho-Abajo.php?TituloIntervencionPadre=".urlencode($Tit ulo_Int_Replica)."&ID_Int_Padre=$ID_Int_Replica Target=Marco3C-DchoInf> $Titulo_Int_Replica</A>");
64 PintarHijos($bd, $ID_Int_Replica, $pref."&nbsp;&nbsp;|---");
65 }
66 }

He probado a no poner global $ID, pero entonces las llamadas recursivas son infinitas.
He probado a pasar el manejador de la BD ($bd), el identificador de la intervención ($ID_Intervencion), y luego los dos a la vez, por referencia, y me ha saltado este error:
"Warning: Ora_Fetch failed (ORA-01002: recuperacion fuera de secuencia -- while processing OCI function OFETCH/OFEN) in C:\Archivos de programa\Apache Group\Apache\htdocs\Fer\Pag_3C-dcho-arriba.php on line 59"

En fin, sigo abierto a sugerencias, o ideas, porque yo ya he agotado las mías.

Por qué es tan difícil trabajar con la función ora_fetch???

Venga chicos, un saludo, y, como siempre, muchas gracias!
  #22 (permalink)  
Antiguo 11/04/2005, 06:38
 
Fecha de Ingreso: marzo-2005
Mensajes: 163
Antigüedad: 12 años, 9 meses
Puntos: 0
No deberias de pasar la $db como referencia, ya que por lo visto ora_fetch($bd) necesita de $db para saber sobre la consulta realizada. Cuando vuelves de la recursion no recupera el estado, sino que mantiene la ultima consulta que se hizo. No se si explico mas o menos bien lo que a mi entender es un error que tienes. Supongo, o intentaria probar, de no pasar ninguna variable por referencia, que todas sean por copia valor y ver que pasa. En el caso de nicolaspar que pasa la conexion por referencia no hay problemas porque trabaja con un resulset que es local entonces no hay drama.
Saludos
  #23 (permalink)  
Antiguo 11/04/2005, 09:19
 
Fecha de Ingreso: abril-2005
Mensajes: 16
Antigüedad: 12 años, 8 meses
Puntos: 0
Gracias MartinTandil !!

Pero me temo que en mi función los parámetros siempre los paso por valor (por copia valor). Lo que os comentaba es que, a falta de más ideas, "había probado suerte", a ver si el problema era que había que pasar alguna de las variables por referencia, pero ya he visto que no, y ahora la función vuelve a tener todos los parámetros declarados por valor, como al principio.

Gracias de todas formas!

Última edición por NaughtyFer; 11/04/2005 a las 09:52
  #24 (permalink)  
Antiguo 11/04/2005, 10:56
 
Fecha de Ingreso: abril-2005
Mensajes: 16
Antigüedad: 12 años, 8 meses
Puntos: 0
Una pregunta rápida.

Si alguno de vosotros ha hecho alguna función recursiva en PHP: Habeis tenido que cambiar alguna de las variables del fichero php.ini??? Es que estaba pensando si tal vez el error podría venir por ello.

Venga, un saludo!!
  #25 (permalink)  
Antiguo 11/04/2005, 11:52
 
Fecha de Ingreso: octubre-2004
Ubicación: En algún lugar de la República Oriental del Uruguay
Mensajes: 366
Antigüedad: 13 años, 1 mes
Puntos: 0
yo no he necesitado cambiar php.ini
  #26 (permalink)  
Antiguo 11/04/2005, 15:00
Avatar de nicolaspar  
Fecha de Ingreso: noviembre-2004
Ubicación: Villa Ballester Bs-As|Ar
Mensajes: 2.002
Antigüedad: 13 años
Puntos: 34
Yo tampoco, las veces que hice una función de estas, funciono en la primera.
Lo único, en mi primera recurciva, tenia problemas con la conexion a la db, por lo que la declare adentro y funcionaba, pero cada vez que iteraba abría una nueva conexión y era imprudente, por eso opte de pasarla por referencia.

Te puedo decir (al menos yo lo haría), de pasar la estructura esa a mysql, y hacer lo mismo con mysql_xxx, solo para saber si el probelma esta las funciones de oracle, las cuales he usado dos veces en cosas simples, no puedo decirte mas. Son como mucho una hora de trabajo, y te sacaras la duda.
__________________
Mi punto de partida es Que Bueno Lo Nuevo

Última edición por nicolaspar; 11/04/2005 a las 15:01
  #27 (permalink)  
Antiguo 13/04/2005, 07:12
 
Fecha de Ingreso: abril-2005
Mensajes: 16
Antigüedad: 12 años, 8 meses
Puntos: 0
Esto ya está!!!



Hola de nuevo a todos!! Antes de nada, quiero daros las gracias a todos los que os habeis tomado la molestia de leer y responder a mis peticiones de ayuda.

Al final, con un poco (bastante) de ayuda externa, he conseguido sacar el dichoso procedimiento recursivo. No ha sido una solución muy elegante que digamos, peeeeero, funciona, y sigue siendo recursiva.

De hecho, la persona que me ha ayudado (mil gracias Javi!! ), ha tenido el valor de "pensar" en otra posible solución, pero implementada directamente en PL/SQL.

En fin, si alguno de vosotros está interesado en que le aclare un poco más cuál era el problema, o que postee el código, no tiene más que decirlo, así que, sin más me despido.... Pero sólo hasta que surja el próximo problema!!

Un saludo [email protected]!!
  #28 (permalink)  
Antiguo 13/04/2005, 09:18
Avatar de nicolaspar  
Fecha de Ingreso: noviembre-2004
Ubicación: Villa Ballester Bs-As|Ar
Mensajes: 2.002
Antigüedad: 13 años
Puntos: 34
Por supuesto que si, podrías poner ese codigo!.


PD: No habras caído en la tentación de usar un cursor en PL no?
__________________
Mi punto de partida es Que Bueno Lo Nuevo
  #29 (permalink)  
Antiguo 13/04/2005, 10:30
 
Fecha de Ingreso: abril-2005
Mensajes: 16
Antigüedad: 12 años, 8 meses
Puntos: 0
Pues sip!!

La solución en PL/SQL efectivamente implica el uso de un cursor... Cómo lo sabes? Lo intuías? O es que ya te has visto en la situación de tener que usarlo?

La otra la posteo a continuación, por si a alguien le puede servir. Una de las claves estaba en un contador de intervenciones que se declara 'global', pero que luego se asigna a una variable local a la función de forma que no se "macahca". En fin, lo dicho, hoy estoy contentísimoooooo!!!

(Ahí va la ya "famosa" función recursiva en PHP):

11 function PintarHijos($bd, $ID_Intervencion, $Titulo_Intervencion, $pref)
12 {
13 global $ID, $Tit, $cuenta_replicas;
14
15 $ID = $ID_Intervencion;
16 $Tit = $Titulo_Intervencion;
17
18 $sql1 = "begin SELECT COUNT(*) INTO :cuenta_replicas FROM REPLICA WHERE ID_Int_precede = :ID; end;";
19 ora_parse($bd, $sql1, 0);
20 ora_bind($bd, "cuenta_replicas", ":cuenta_replicas", 8);
21 ora_bind($bd, "ID", ":ID", 10, 1);
22 $cuenta_replicas = NULL;
23 ora_exec($bd);
24
25 $aux = $cuenta_replicas;
26 $sql2 = "SELECT ID_Int, Titulo_Intervencion FROM REPLICA WHERE (ID_Int_precede = :ID)";
27 ora_parse($bd, $sql2, 0);
28 ora_bind($bd, "ID", ":ID", 10, 1);
29 ora_exec($bd);
30 for ($i=1;$i<=$cuenta_replicas;++$i)
31 {
32 ora_fetch($bd);
33 $cad_id[$i]= trim(ora_getcolumn($bd, 0));
34 $cad_tit[$i]= trim(ora_getcolumn($bd, 1));
35 }
36 for ($i=1;$i<=$aux;++$i)
37 {
38 $ID_Int_Replica = $cad_id[$i];
39 $TituloIntPadre = $cad_tit[$i];
40 print("<BR>".$pref."<A HREF=Pag_3C-Dcho-Abajo.php?TituloIntervencionPadre=".urlencode($Tit uloIntPadre)."&ID_Int_Padre=$ID_Int_Replica Target=Marco3C-DchoInf> $TituloIntPadre</A>");
41 PintarHijos($bd, $cad_id[$i], $cad_tit[$i], $pref."&nbsp;&nbsp;|---");
42 }
43 }

Venga, un saludo a [email protected]!! Bye!!
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 08:16.