Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   PHP (https://www.clubdelphi.com/foros/forumdisplay.php?f=15)
-   -   Menú dinámico con JavaScript y PHP (https://www.clubdelphi.com/foros/showthread.php?t=50656)

lucasarts_18 24-11-2007 04:14:19

Menú dinámico con JavaScript y PHP
 
Hola comunidad,

Les comento que tengo implementado un menú dinámico hecho mediante javascript y php y que en mi PC funciona correctamente tanto en Firefox y IE6, debo decir además que en mi PC yo configure el PHP, MySQL y Apache 2.0.

Por otra parte he instalado en mi notebook el AppServ y fue en realidad por flojera (es mas rápido...:D) y carge mis páginas, pero al momento de cargar el menú dinámico este no aparece simplemente.

Les dejo el código que cree para implementar este menu tipo "arbolito"

Código PHP:

var TREE_NODES={
 format:{
  left:0,
  top:86,
  width:220,
  height:600,
  e_image:"../../images/fo_p.gif",
  c_image:"../../images/fc_p.gif",
  i_image:"../../images/i_p.gif",
  b_image:'../../images/b.gif',
  bgcolor:"#d4d0c8",
  back_bgcolor:"#d4d0c8",
  animation:0,
  padding:2,
  level_ident:10,
  dont_resize_back:1
 },
 sub:[
  {html:'Sistema Cabo V 1.0',
   sub:[
   <?php
   session_start
();
   
$link mysql_connect("localhost","root","160783");
   
mysql_select_db("cabo");
   
$idPerfil $_SESSION['idPerfil'];
   
$resultPadre mysql_query("select distinct m.grupo
                                     from perfiles p
                                     inner join
                                       perfiles_menus mp on p.idperfil = mp.idperfil
                                     inner join menus m on mp.idmenu = m.idmenu
                                     where p.idperfil = 
$idPerfil",$link);
              
$totalFilasPadre mysql_num_rows($resultPadre);
              
$contPadre 1;
              while(
$rowPadre mysql_fetch_array($resultPadre,MYSQL_NUM)){
                
$rowGrupo $rowPadre[0];
                echo 
"{html:'$rowPadre[0]',";
                echo 
"sub:[";
                  
$resultHijo mysql_query("select m.*
                                             from perfiles_menus pm
                                               inner join menus m on pm.idmenu = m.idmenu
                                             where pm.idperfil = 
$idPerfil
                                               and m.grupo = '
$rowGrupo'",$link);
                  
$totalFilas mysql_num_rows($resultHijo);
                  
$cont 1;
                  while(
$rowHijo mysql_fetch_array($resultHijo,MYSQL_NUM)) {
                   if (
$cont $totalFilas)
                   echo 
" {html:'$rowHijo[1]', url:'$rowHijo[2]'},";
                   else
                    echo 
" {html:'$rowHijo[1]', url:'$rowHijo[2]'}";
                   
$cont++;
                  }
                  echo 
"]";
                  if (
$contPadre $totalFilasPadre)
                    echo 
'},';
                  else {
                    echo 
'}';
                  }
                  
$contPadre++;
          }
   echo 
']';
 
  echo 
'}';
 echo 
']';
echo 
'}';
?>

Este código funciona bien en mi pc pero no en mi notebook....:( y el firefox de mi notebook dice el siguiente error:

invalid falg after regular expression (Linea 22)
TREE_NODES is not defined (Linea 39)

Mi pregunta es: ¿Existe alguna configuración especial en el archivo ini para las expresiones regulares?, ¿Es posible?

Esperando la respuesta de todos los maestros.........realmente la necesito, me tiene desconcertado este error.:eek:

Gracias

Hasta Luego .-

dec 24-11-2007 11:14:28

Hola,

A ver si podemos ayudar en algo. :) Digo yo que, ¿el error que te aparece lo imprime PHP, o, según entiendo, es el navegador (acaso la extensión FireBug) la que te muestra el mensaje de error? Porque la variable "TREE_NODES" es una variable de JavaScript, ¿no?

Por otro lado, en el código no veo que hagas uso de ninguna expresión regular... y, si seguimos los mensajes de error y miramos en la línea 22 y 39 del código que muestras, pareciera que ahí no hay ningún error, o que las líneas no coinciden, vaya...

La cosa es que te funciona en un sitio y en otro no... ¿se trata de la misma versión de PHP? ¿Qué extensión tiene el Script problemático? A ver si va a ser un archivo ".js" y, en el sistema en que obtienes el error, este tipo de archivos no es procesado como PHP, como por otro lado es lo normal...

No sé... a ver si damos con la tecla entre todos. :)

lucasarts_18 24-11-2007 17:51:24

Primero que nada gracias por responder compañero Dec.

Cita:

Empezado por dec
es el navegador (acaso la extensión FireBug) la que te muestra el mensaje de error? Porque la variable "TREE_NODES" es una variable de JavaScript, ¿no?

Así es, el error lo notifica Javascript mediante la consola de error del FireFox (no Firebug), y "TREE_NODES" es una variable JS.

Cita:

Empezado por dec
La cosa es que te funciona en un sitio y en otro no... ¿se trata de la misma versión de PHP?

No se trata de la misma versión de PHP, en mi PC yo hice la instalación de PHP 5.2.0, Apache 2.0.52 por separado, y en mi notebook instale el AppServ con Php 5.2.3 y Apache 2.2.4

Cita:

Empezado por dec
¿Qué extensión tiene el Script problemático?

Extensión PHP, ahí coloco texto que en el PC lo interpreta correctamente como javascript y también texto de PHP como se ve en el primer mensaje de este hilo, pero que con AppServ y en la otra máquina no funka...:(

ese archivo php lo gatillo de la siguiente forma.

Código PHP:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<
html>
<
head>
<
link rel="stylesheet" href="../../css/conf_tree.css" type="text/css">
<
link rel="stylesheet" href="../../css/conf_principal.css" type="text/css">
<
script language="JavaScript" src="../../jscripts/sdtree.js" type="text/javascript"></script>
<script language="JavaScript" src="../../jscripts/structure_tree.php" type="text/javascript"></script>
<script language="JavaScript" src="../../jscripts/conf_tree.js" type="text/javascript"></script>
</head>
<body style="margin: 0px"> 
<table border="0" width="99%" cellpadding="0" cellspacing="0" class="headerBackground">
<tr><!-- width="1017" -->
<td height="60" valign="bottom" align="center" class="letraHeader">Sistema de Embalaje Cabo</td>
</tr>
<tr>
<td height="23" align="right" valign="top" class="headerLogin">&nbsp;
Usuario conectado: {$nomUsuario} | Perfil: {$nomPerfil} </td>
</tr>
</table>
</body>
</html> 

allí se puede ver como la página carga el archivo
../../jscripts/structure_tree.php y que es el archivo encargado de generar el arbolito dinámico mediante Javascript y PHP en un archivo con extensión PHP.

Dec, espero haber aclarado tus dudas y que tengas mas información para ver el problema que tengo, gracias nuevamente.

Hasta Luego .-

dec 24-11-2007 18:01:53

Hola,

Bueno. La expresión regular debe ponerla por su parte el Script que usas para crear el "treeview". Se me ocurren varias cosas, pero, te preguntaría si las pruebas las haces con la misma base de datos, con los mismos datos.

Haces una cosa que acaso sea problemática y que tiene que ver con esto último. "Imprimes" los datos que traes de la base de datos "tal cual", cuando, a lo mejor es preciso "escaparlos", para evitar problemas. Más aún si estos datos van a ir dentro de "comillas", por ejemplo.

Personalmente uso esta función cuando tengo que imprimir un dato procedente de la base de datos en HTML, para evitar problemas:

Código PHP:

  static public function Str2Htm($input,$charset='utf-8'){
    return 
htmlentities(strip_tags(
     
stripslashes($input)),ENT_QUOTES,$charset);
  } 

Esto viene a cuento de que, por ejemplo, si recibes de la base de datos algo como "O'connor", es posible que la "comilla simple" rompa el Script en que estás insertando el dato en cuestión. O si recibes otros símbolos como "\", es posible que esto rompa el Script, expresiones regulares, etc. Es posible que me equivoque, pero, yo miraría por ahí... para empezar, por lo menos. :)

lucasarts_18 24-11-2007 19:24:18

Cita:

Empezado por dec (Mensaje 248209)
Código PHP:

  static public function Str2Htm($input,$charset='utf-8'){
    return 
htmlentities(strip_tags(
     
stripslashes($input)),ENT_QUOTES,$charset);
  } 

Esto viene a cuento de que, por ejemplo, si recibes de la base de datos algo como "O'connor", es posible que la "comilla simple" rompa el Script en que estás insertando el dato en cuestión. O si recibes otros símbolos como "\", es posible que esto rompa el Script, expresiones regulares, etc. Es posible que me equivoque, pero, yo miraría por ahí... para empezar, por lo menos. :)

Entonces a cada Echo que haga en mi script debo mandarle esta función, esa función recibe dos parametros, que se supone que le mando al segundo parámetro ?

¿Podrías darme un ejemplo?

Gracias.

Hasta Luego .-

dec 24-11-2007 20:16:27

Hola,

Hombre, a cada "echo"... pero sí tienes que hacerlo "a discrección". El segundo parámetro es para indicárselo a la función en que es preciso y tiene que ver con el "charset" que estés utilizando, tanto en la página Web como en la base de datos. Yo tengo por defecto "utf-8", puesto que el "charset" que procuro usar.

Respecto del ejemplo. Ahí va uno más bien sencillo, porque, te advierto que yo en esto tampoco me llego a aclarar del todo, si bien es cierto que, efectivamente, intuyo que por ahí pueden ir los tiros en este caso... lo mismo hasta en esto estoy equivocado.

Código PHP:

<?php

$value 
"Pedrolopez\\";

//$value = Str2Htm($value);

?>

<p onclick="alert('<?php echo $value ?>')">
Un párrafo sobre el que se puede hacer clic
</p>

Si ejecutas el código anterior verás que el "alert" no funciona. Sé que es algo forzado, que acaso no encuentres nunca un registro en la base de datos que contenga esa "barra invertida", pero, piensa que esto se hace también para evitar el que pueda insertarse un registro así... adrede.

Ahora, si "descomentas" la instrucción en que se hace pasar el "valor" por la función "Str2Htm()" verás que el "alert" de JavaScript funciona como se espera, porque, no se corta la cadena que se supone ha de mostrar.

Sin embargo, no nos vamos a engañar, yo esperaba que algo así también funcionase:

Código PHP:

$value = "Jhon O'Connor";

$value = GbValidate::Str2Htm($value);

?>

<p onclick="alert('<?php echo $value ?>')">
Un párrafo sobre el que se puede hacer clic
</p>

Pero, no lo hace. Porque, aunque la comilla "simple" del valor se convierte a su correspondiente "entidad", lo cierto es que JavaScript "reconoce" dicha entidad, la toma como la comilla simple que es y, ¡zas!, el "alert" no funciona como se espera...

No sé. Prueba por ese camino. Sobre esto del escapar cadenas hay que llevar cierto cuidado. Por ejemplo, si la cadena va a mostrarse dentro de un "input" o "textarea" yo, por lo pronto, no las escapo. Si ha de mostrarse en otro lugar sí que lo hago.

Y, a la contra pasa lo mismo, me refiero a que cuando guardas valores en la base de datos estos han de ser previamente escapados, pero, no con la función que antes copié aquí. Yo, para estos menesteres, uso esta otra función, que me recomendó un conocido hace bastante tiempo:

Código PHP:

  public function Escape($input){
    if(
get_magic_quotes_gpc()){
      
$input stripslashes($input);
    }
    return @
mysql_real_escape_string(
     
$input$this->dbConnection);
  } 

Se trata de escapar con esa función cualquier cadena que vaya a formar parte de una consulta SQL. Y sirve, entre otras cosas, para evitar el "SQL injection" ese de que tanto se habla, o de que tan poco se habla...

Puede parecer "pesado" tener que hacer algo así cuando insertas registros, por un lado, y cuando los muestras, por otro, pero, no queda otra. A no ser que controles absolutamente a los usuarios de la aplicación y estos no vayan a pretender nunca "meter la pata", pero, aún así...

Por ejemplo, si vas a imprimir un determinado valor dentro de HTML, como poco, es menester escapar las posibles etiquetas HTML que dicho valor contenga, como, por ejemplo, < script >... que puede estar ahí con mala idea...

No sé si te estoy ayudando en algo o no Lúcas, pero, en fin, como he dicho más arriba, a ver si entre todos sacamos algo en claro. :)

lucasarts_18 24-11-2007 20:26:50

Hola Dec,

Pues mi desconcierto es aún mayor cuando empecé hacer pruebas a "locas", pues me encuentro que al sacar el session_start() y reemplazar la variable de session por un valor fijo funciona de maravilla el script, y ojo !!!! que no estoy soñando, vuelvo agregar el session start y deja de funcionar........:confused:

Creo que las cosas de ahora en adelante cambian o no dec ?, pero eso de escapear las variables es una muy buena práctica de programación, pero los tiros no van por ahí por lo mencionado mas arriba.

Hasta Luego .-

lucasarts_18 24-11-2007 20:31:28

Arreglado
 
Hola Dec

Asunto arreglado el session_start debe estar antes de una salida al navegador, lo puse al comienzo y asunto arreglado, ahora mi pregunta es ¿por qué diablos funciona en la otra máquina.?

Hasta Luego .-

dec 24-11-2007 20:35:54

Hola,

Bueno. Pues las cosas cambian, pero, permíteme insistir en lo dicho de escapar cadenas (de entrada en la base de datos y de salida para imprimir), puesto que, como ves, usas el valor de la variable de la sesión dentro de la consulta SQL sin escaparlo antes: y eso puede traer problemas de seguridad... alguien podría "inyectar" SQL ahí.

Pero, dejando este tema aparte y volviendo al asunto primero de este hilo... pues... ¿qué hay exactamente en la variable de la sesión? Yo probaría a dejar el "session_start()", pero, a poner un valor fijo en la variable de marras. No creo que "session_start()" de problemas (vamos, no veo porqué), pero, el valor... quién sabe qué valor es...

Yo echaría un vistazo al valor de esa variable, por un lado, y luego a lo que me retorna la consulta SQL, imprimiría lo que me retorna y vería qué puede haber raro ahí. Por otro lado, no has comentado al respecto, pero, ¿se supone que "juegas" con los mismos datos? En donde funciona y en donde no, me refiero, porque el problema podría estar en los datos... unos son problemáticos y los otros no.

Y más aún... creo que los tiros siguen siendo por donde he mencionado, porque me ciño al mensaje de error: se encuentra algún carácter no esperado en la expresión regular que usa el Script que utilizas para componer el menú. Ahora bien, ¿de dónde sale ese carácter problemático? No puede ser de otro modo: vienen de la base de datos...

Así que, resumiendo, vería qué contiene la variable de sesión. Y luego probaría, como has hecho, los resultados que obtengo con un valor fijo, pero, dicho valor ha de ser el que se supone que debería tener la variable de sesión, con el fin de que los datos que vienen de la base de datos sean los mismos: porque de no ser así, unos pueden contener caracteres "problemáticos", pero, otros no.

Vamos... digo yo. :)

lucasarts_18 24-11-2007 20:54:37

Cita:

Empezado por dec
Hola,

Bueno. Pues las cosas cambian, pero, permíteme insistir en lo dicho de escapar cadenas (de entrada en la base de datos y de salida para imprimir), puesto que, como ves, usas el valor de la variable de la sesión dentro de la consulta SQL sin escaparlo antes: y eso puede traer problemas de seguridad... alguien podría "inyectar" SQL ahí.

Totalmente de acuerdo.

Cita:

Empezado por dec
Pero, dejando este tema aparte y volviendo al asunto primero de este hilo... pues... ¿qué hay exactamente en la variable de la sesión? Yo probaría a dejar el "session_start()", pero, a poner un valor fijo en la variable de marras. No creo que "session_start()" de problemas (vamos, no veo porqué), pero, el valor... quién sabe qué valor es...

Es un simple valor del idPerfil, en mi caso tengo dos perfiles en la base de datos, 1 y 2. Puse el valor en "bruto" Y deje el session_start en el mismo lugar y sigue dando el problema.

Cita:

Empezado por dec
Por otro lado, no has comentado al respecto, pero, ¿se supone que "juegas" con los mismos datos? En donde funciona y en donde no, me refiero, porque el problema podría estar en los datos... unos son problemáticos y los otros no.

Sos los mismos datos, en realidad en la misma base de datos, porque hice un restore de la misma base de datos que está en la otra máquina.Tienen los mismos registros.

Cita:

Empezado por dec
Así que, resumiendo, vería qué contiene la variable de sesión.
Vamos... digo yo. :)

La variable de sessión trae un 1 o un 2.

Seún la web de php dice esto.

[quote=sitiophp]

Nota: Si está usando sesiones basadas en las cookies, debe llamar a session_start() antes de que haya ninguna salida al navegador.

[/sitiophp]

Y ahora que recuerdo existe una directiva en php.ini que en estos momentos no recuerdo su nombre que permite sacar salidas al navegador antes de enviar un session_start().

no sé, no sé, yo apuesto a lo que dice la web de php y que el session_start debe ir antes que haya una salida al navegador, ya que la variable que trae la variable de session siempre es 1 o 2, y los registros de la base de datos son los mismos.

Gracias por todo....

Espero tu comentario.

Nos vemos.

dec 24-11-2007 20:59:58

Hola,

Bueno, es que de hecho, ahora que lo mencionas, efectivamente, no se puede (?) iniciar una sesión de usuario si ya se enviaron algunas cabeceras HTTP... y cuando enviamos contenido ya hemos hecho eso. Pues oye, por ahí pueden ir los tiros, sí. Diste en el clavo.

Ahora faltaría saber cómo es que un lugar funciona y en otro no, pero, yo creo que el asunto apunta a lo que dices: puede que cierta configuración de PHP (tal vez incluso de Apache) haga que el que no se pueda enviar nada antes de iniciar sesión no sea tan así...

De todas formas, es extraño. Porque, si me dijeras, bueno, es que no puedes enviar contenido antes de iniciar sesión, y, si lo haces, los resultados son inesperados... pues vale. Pero, si me dices que la variable de sesión que utilizas trae el valor "correcto" en todo caso... pues chico, no sabe uno qué pensar.

En todo caso, efectivamente, no cuesta nada poner ese "session_start()" antes de enviar salida alguna, de modo que comprobemos si así funciona... en ambos sitios. ;)

PD. No había visto el mensaje:

Cita:

Empezado por Lúcas
Asunto arreglado el session_start debe estar antes de una salida al navegador, lo puse al comienzo y asunto arreglado, ahora mi pregunta es ¿por qué diablos funciona en la otra máquina.?

Y ahí está la madre del cordero, pero, como he dicho, creo que apuntas bien... debe ser "algo" en la configuración de PHP... o Apache... pero, en todo caso, teniendo cuidado de no enviar nada antes de iniciar la sesión, y funcionando así en todos lados... oyes, a lo mejor tampoco hay que dar más de sí el tema, que bastante te ha comido el coco. :) Aunque, por otro lado, estas cosas gusta saber porqué pasan... No sé... no sé... :D

lucasarts_18 24-11-2007 21:18:18

Hola Dec,

Encontre en la otra máquina porque sí funcionaba el asunto, efectivamente era una directiva del php.ini (no tengo tan mala memoria decía un sabio, jeje :))
y la directiva que permite modificar ese comportamiento en php es la siguiente.

output_buffering = On

Así estaba en la máquina que siempre había funcionado

output_buffering = Off

Así estaba en la máquina que no funcionaba.

Pero vemos que dice esta directiva en el propio comentario del php.ini :D

Código:

; Output buffering allows you to send header lines (including cookies) even
; after you send body content, at the price of slowing PHP's output layer a
; bit.  You can enable output buffering during runtime by calling the output
; buffering functions.  You can also enable output buffering for all files by
; setting this directive to On.  If you wish to limit the size of the buffer
; to a certain size - you can use a maximum number of bytes instead of 'On', as
; a value for this directive (e.g., output_buffering=4096).

Ahí está la respuesta a este quebradero de coco. jeje.

Hasta Luego .-

dec 24-11-2007 21:25:07

Hola,

Pues a mí no me queda tan claro... o sea, que sí, que uno puede usar esa directiva en caso de tener la necesidad (podrá darse el caso, digo yo) de enviar cabeceras HTTP incluso luego de haber enviado cierto contenido, pero, ¿y qué más?

Porque no veo que diga (pero mi inglés es muy malo) algo así como "y si usted no usa esta directiva y envía contenido y después trata de enviar cabeceras HTTP, entonces los resultados de su script serán pueden ser impredecibles"... ¿O qué? :D

Pero, no te quiero comer el coco Lúcas... me alegro de que dieras con la tecla, incluso si a mí no me queda claro por qué ocurría el error... qué era lo que lo provocaba, al cabo. ¿O es que me estoy perdiendo algo? Mira que no me extrañaría. :)

lucasarts_18 24-11-2007 21:40:41

Dec, yo lo veo así, en la máquina que tiene activado esta directiva permite enviar contenido antes de hacer uso de funciones como session_start, de ahí que el menú siempre funcionaba, hay que mirar que el código del menú al comienzo el solo javascript, por lo tanto se enviaba este código antes del session_start y funcionaba de maravilla porque estaba activada esta directiva en el php.ini.

En la otra máquina pues no estaba activada esa directiva por lo tanto fallaba, de ahí que cambiara el session_start al comienzo del script y funcionó.

y sí efectivamente esa directiva al tenerla activada permite enviar salidas al navegar antes que el envío de cabeceras HTTP.

Hasta Luego .-

dec 24-11-2007 22:13:54

Hola,

¿Quieres decir que de ahí que JavaScript no encontrara la variable "TREE_NODES", porque esta, en realidad, no era enviada? Ajá... pues entonces, claro, ahí puede estar la madre del cordero, como suele decirse. :) ;)


La franja horaria es GMT +2. Ahora son las 10:44:16.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi