Foro de elhacker.net

Programación => Desarrollo Web => Mensaje iniciado por: Leguim en 1 Septiembre 2020, 04:43 am



Título: [Pregunta]: Variable global (javascript)
Publicado por: Leguim en 1 Septiembre 2020, 04:43 am
Hola,

estoy teniendo problemas con un código, defino una variable con una cadena ("texto") antes de una llamada ajax, pero después cuando quiero usar esa variable de javascript en el fichero php de ajax no me está dejando y me dice que no está definida.

Código
  1. // page.php
  2. <?php
  3. if($x >= $y)
  4. {
  5.         ?>
  6.         <script>
  7.         $(document).ready(function()
  8.         {
  9.               var my_variable = 'texto'; // defino la variable
  10.               Ejecuta_Ajax();
  11.         });
  12.         </script>
  13.         <?php
  14. }
  15. ?>
  16.  

Código
  1. // voy a saltarme la llamada de ajax en javascript/jquery ($.ajax) y paso directamente al fichero php que será llamado en dicha solicitud
  2. // fichero_ajax.php
  3. <?php
  4. //
  5.          ?>
  6.          <script>
  7.          $(document).ready(function()
  8.          {
  9.                    console.log(my_variable); // va a decirme que no está definida dicha variable.
  10.          });
  11.          </script>
  12.          <?php
  13. //
  14. ?>
  15.  

Entiendo que puedo enviar "my_variable" como parámetro en la función "Ejecuta_Ajax(my_variable);" y recibirla en el fichero ya como un dato PHP pero para este caso no aplica para lo que estoy intentando.

Simplemente saber si existe alguna manera o no de poder definir esa variable de una forma más global porque no tengo muy en claro que es lo que está pasando.

Gracias.


Título: Re: [Pregunta]: Variable global (javascript)
Publicado por: WHK en 1 Septiembre 2020, 04:51 am
Hola, primeramente, siempre se recomienda separar el código de php y javascript en archivos distntos, todo lo que tenga lógica debe ir en tu código php y todo lo estático en tu código javascript en un archivo .js.

Por otro lado, tu variable queda dentro de "$(document).ready(function()" y no sale de esta, por eso es recomendable que todo tu código esté por lo menos en un mismo archivo a menos que te independices de las constantes globales y uses variables desde respuestas json desde php.

Puedes solucionarlo rápido declarando "var my_variable" fuera del jquery, pero de todas maneras es una mala práctica porque nadie te asegura que nunca va a fallar la carga de un php con un código y tendrás que escribir demasiadas comprobaciones, en ves de eso simplemente pon todo en un mismo archivo .js y ya.

Saludos.


Título: Re: [Pregunta]: Variable global (javascript)
Publicado por: Agente Naranja en 8 Septiembre 2020, 05:41 am
Lo que declaras dentro de una función desaparece cuando termina la función.

Por ejemplo

Código
  1. let a = 10
  2. function changeA() {
  3.   let a = 20;
  4. }
  5.  
  6. changeA();
  7. console.log(a); // imprime 10
  8.  

El resultado por pantalla es 10, porque dentro de tu funcion has declarado una nueva "a", que existe solamente dentro de la función.

Ahora bien, si dentro de la función no declaras una nueva, sino que reusas el nombre de fuera, entonces sí que javascript te modificará la variable externa.

Código
  1. let a = 10
  2. function changeA() {
  3.   a = 20;
  4. }
  5.  
  6. changeA();
  7. console.log(a); //imprime 20
  8.  

Como ves, la única diferencia es que ya no uso "let", por lo tanto no digo "declara una nueva variable con nombre a", sino "usa la variable que encuentres con el nombre a, si no encuentras ninguna, entonces crea una para mi función". Mira por ejemplo:

Código
  1. function init() {
  2.   a = 123
  3. }
  4.  
  5. console.log(a)
  6.  

Te resultará en un error "Uncaught ReferenceError: a is not defined" porque la variable solamente existe dentro de la función

Espero que te haya aclarado algo


Título: Re: [Pregunta]: Variable global (javascript)
Publicado por: @XSStringManolo en 9 Septiembre 2020, 04:02 am
El código PHP no va a existir en absolutamente ningún momento en el navegador. El servidor es quien procesa en el código PHP y te mandan una web como si el PHP no existiera.

El resultado que mandas al navegador es este:
Código
  1. <body>
  2. <script>
  3. $(document).ready(function() {
  4.  var my_variable = 'texto'; // defino la variable
  5.  Ejecuta_Ajax();
  6. });
  7. </script>
  8.  
  9. <script>
  10. $(document).ready(function() {
  11.  console.log(my_variable); // va a decirme que no está definida dicha variable.
  12. });
  13. </script>
  14. </body>

Como ya te han comentado y yo mismo te comenté no hace mucho en respuesta a uno de tus temas de forma bastante concreta el uso de var, let, globales y alcances. Al usar var estás definiendo la variable en el contexto de la función "más cercana"(en caso de haberla), no de forma global.

Si quieres definirla de forma global desde dentro de una función lo normal es que la definas explícitamente como propiedad del objeto giobal:
Código
  1. window.my_variable = "texto";

Utilizando librerías palante y ensuciando el alcance global a tutiplen por desconocimiento lo único que vas a conseguir es dolores de cabeza.

Mi consejo cuando programes con PHP y en general es que dejes de utilizar el document ready y en su lugar simplemente coloques todo el código javascript normalmente en un único script en la parte final justo antes de la etiqueta de cierre del body. Dado a como funcionan los parsers no vas a tener problemas porque se procesará el HTML por orden, y como las etiquetas script son HTML, cuando llegues a ellas ya tendrás todo el HTML anterior procesado y listo para manipular.

Cuando tienes todo el codigo al final en un solo script, perfectamente puedes moverlo a un archivo externo como te están aconsejando y a lo que yo me sumo.

Hacer esto tiene muchas ventajas. Como reducir el tamaño total de la web, hacer posibles la implementación de una cuantas medidas de seguridad para evitar multiples exploits, ahorrarte tiempo de portar cambios entre codigo que tengas repetido o incongruencias, facilitar la localización y manejo...

También es viable mover un archivo con funciones puras al head y la implementación/llamadas al body. Es una forma cómoda de separar algunas librerías o posibilitar elementos html custom. Uno de los ejemplos más populares son los templates con las etiquetas script.

He visto que estás acostumbrado a meter muchqs etiquetas script con document.write("ejemplo"). En lugar de hacer esto puedes meter una sola librería para habilitar mustache sintax y así solo necesitas poner {{ ejemplo }} y la librería te lo remplazará. No estoy seguro pero creo que jquery tiene algo así.

En general los frameworks modernos te permiten hacer esto. Te aconsejo vue.js, es el más simple y sencillo. Aunque también tienes librerías independientes muy completas y compactas.