Foros del Web » Programando para Internet » PHP »

Tratando de entender las referencias...

Estas en el tema de Tratando de entender las referencias... en el foro de PHP en Foros del Web. Llevo un lío tremendo con las referencias... Ejemplo Código PHP: <?php function  a (& $a , & $b ) {  $a  =&  $b ;  } $a  =  ...
  #1 (permalink)  
Antiguo 04/07/2010, 16:36
 
Fecha de Ingreso: septiembre-2006
Mensajes: 68
Antigüedad: 18 años, 2 meses
Puntos: 0
Tratando de entender las referencias...

Llevo un lío tremendo con las referencias...
Ejemplo

Código PHP:
<?php
function a(&$a, &$b) { 
$a =& $b
}
$a 1;
$b 2;
a($a$b);
$b 3;
print 
$a;
?>
En la función $a y $b se pasan por referencia, por tanto la función puede modificar su contenido fuera de su ámbito

Dentro de la función está la asignación por referencia $a =& $b, que por definición (http://www.php.net/manual/en/languag...ces.whatdo.php) significa que $a y $b apuntan al mismo contenido

Ahora bien, el resultado de este código es ¿¿1??
¿Alguien podría aclararme por qué?

Una vez aclarado ésto, postearé otras dudas que tengo al respecto, mareando un poco más la perdiz
  #2 (permalink)  
Antiguo 04/07/2010, 17:39
Avatar de mortiprogramador
Colaborador
 
Fecha de Ingreso: septiembre-2009
Ubicación: mortuoria
Mensajes: 3.805
Antigüedad: 15 años, 2 meses
Puntos: 214
Respuesta: Tratando de entender las referencias...

Saludos
Bueno, pues como en efecto lo dices tú mismo, al ser por referencia ellas apuntan al mismo contenido EN EL PUNTO DONDE ESTAN (it means that $a and $b point to the same content. 'extraido del link que pasaste') , es decir, que si dentro de la función pones esto
Código PHP:
Ver original
  1. echo "a ".$a;
  2. echo "b ".$b;
en ambos casos verás 2, pero luego que salen de la función, al estar por referencia y no por valor, las variables conservan sus valores originales

espero se te aclare
saludos
__________________
"Si consigues ser algo más que un hombre, si te entregas a un ideal, si nadie puede detenerte, te conviertes en algo muy diferente."
Visita piggypon.com
  #3 (permalink)  
Antiguo 05/07/2010, 03:15
 
Fecha de Ingreso: septiembre-2006
Mensajes: 68
Antigüedad: 18 años, 2 meses
Puntos: 0
Respuesta: Tratando de entender las referencias...

Cita:
Iniciado por mortiprogramador Ver Mensaje
Saludos
Bueno, pues como en efecto lo dices tú mismo, al ser por referencia ellas apuntan al mismo contenido EN EL PUNTO DONDE ESTAN (it means that $a and $b point to the same content. 'extraido del link que pasaste') , es decir, que si dentro de la función pones esto
Código PHP:
Ver original
  1. echo "a ".$a;
  2. echo "b ".$b;
en ambos casos verás 2, pero luego que salen de la función, al estar por referencia y no por valor, las variables conservan sus valores originales

espero se te aclare
saludos
Vaya! Y tanto que me lo has aclarado!!
Pero entonces, ¿qué diferencia hay entre pasar variables por referencia a una función y pasarlas por valor?

Quiero decir...
Este otro código

Código PHP:
<?php
function a($a$b) { // ya no pasamos por referencia
$a =& $b
}
$a 1;
$b 2;
a($a$b);
$b 3;
print 
$a;
?>
¿No daría el mismo resultado?
¿No se supone que la "gracia" de pasar variables por referencia a una función está en que la función puede modificar esas variables fuera de su ámbito (scope), aunque la función no devuelva nada?
  #4 (permalink)  
Antiguo 05/07/2010, 05:57
Avatar de abimaelrc
Colaborador
 
Fecha de Ingreso: mayo-2009
Ubicación: En el planeta de Puerto Rico
Mensajes: 14.734
Antigüedad: 15 años, 5 meses
Puntos: 1517
Respuesta: Tratando de entender las referencias...

Lo que sucede es que eso sí está haciendo referencia pero dentro del alcance de las variables en una función. Para que puedes hacer referencia a una variable debes declararlo fuera de la función y luego todo cambio que hagas dentro de la función a la referencia se verá reflejado. Algo así
Código PHP:
Ver original
  1. <?php
  2. $a = 'foo';
  3. $b = 'bar';
  4. function foo(&$c, $d){
  5.     $c = $d;
  6. }
  7. foo($a,$b);
  8. echo $a . ' = ' . $b; // imprime bar = bar
Si te fijas no usé el return y tampoco le asigné a la variable $a la función foo () pero se modificó la variable $a, porque pasé por referencia el primer argumento que contiene la información de la variable $a. Te recomiendo que repases sobre el alcance de las variables y también la parte de referencia.
__________________
Verifica antes de preguntar.
Los verdaderos amigos se hieren con la verdad, para no perderlos con la mentira. - Eugenio Maria de Hostos
  #5 (permalink)  
Antiguo 05/07/2010, 06:55
 
Fecha de Ingreso: septiembre-2006
Mensajes: 68
Antigüedad: 18 años, 2 meses
Puntos: 0
Respuesta: Tratando de entender las referencias...

Cita:
Iniciado por abimaelrc Ver Mensaje
Lo que sucede es que eso sí está haciendo referencia pero dentro del alcance de las variables en una función. Para que puedes hacer referencia a una variable debes declararlo fuera de la función y luego todo cambio que hagas dentro de la función a la referencia se verá reflejado. Algo así
Código PHP:
Ver original
  1. <?php
  2. $a = 'foo';
  3. $b = 'bar';
  4. function foo(&$c, $d){
  5.     $c = $d;
  6. }
  7. foo($a,$b);
  8. echo $a . ' = ' . $b; // imprime bar = bar
Si te fijas no usé el return y tampoco le asigné a la variable $a la función foo () pero se modificó la variable $a, porque pasé por referencia el primer argumento que contiene la información de la variable $a. Te recomiendo que repases sobre el alcance de las variables y también la parte de referencia.
Sí, si tu código lo entiendo
Hace lo que supondría que tiene que hacer

Creo que mi problema es que no he entendido qué hace exactamente =&

$a =& $b; // $a y $b apuntan al mismo contenido... pero ¿a qué contenido? ¿al de $a? ¿al de $b?

Si ejecuto ésto...
Código PHP:
$a 1;
$b 2;
$a =& $b;
print 
$a// $a es 2
$a 4;
print 
$b// $b es 4 
Por tanto, de aquí deduzco que si ninguna de las variables cambia, cuando realizamos el =& el valor que se toma es el último que se haya definido ¿Es ésto correcto?
  #6 (permalink)  
Antiguo 05/07/2010, 07:56
 
Fecha de Ingreso: septiembre-2006
Mensajes: 68
Antigüedad: 18 años, 2 meses
Puntos: 0
Respuesta: Tratando de entender las referencias...

Vale, creo ya lo he pillado

Código PHP:
$var 'foo';
function 
foo(&var){
    
$b 'baz';
    
$var =& $b// si hacemos return $var la función devolvería baz
}
foo($var);
echo 
$var// en cambio, fuera de la función $var sigue siendo foo 
Osea...
Las referencias dentro de la función, aunque los argumentos estén pasados por referencia, sólo afectan dentro de la función

No le veo mucha lógica (dentro de la función $var cambia, de igual modo que si en la función ponemos $a = $b;), pero voy a tener que creérmelo!!
  #7 (permalink)  
Antiguo 05/07/2010, 11:03
Avatar de wiwi74  
Fecha de Ingreso: marzo-2008
Mensajes: 515
Antigüedad: 16 años, 8 meses
Puntos: 10
Respuesta: Tratando de entender las referencias...

Para que le veas el sentido:

Un ejemplo sencillo:

Código PHP:

$a 
1;

$b = &$a;


echo 
$a."<br />";

echo 
$b."<br />"
Seria $a = $b que sentido tiene usar &

Pues lo tiene:

$a = 1;
Aqui le dimos a $a el valor de 1, o sea almacenamos en memoira (ram) el valor de $a.

$b = &$a;
Aqui le "damos" a $b el valor de $a. Pero en memoria habra un solo valor almacenado "1" Y Ambas variables apuntaran hacia ese valor (las dos valdran 1) Lo cual no es lo mismo que hacer esto $b = $a ya que aqui cada una ocupara su lugar en memoria.

Una forma de hacer economia...

Del manual:
Note: $a y $b son completamente iguales, no es que $a esté apuntando a $b o viceversa, sino que tanto $a como $b apuntan al mismo lugar (agrego: en memoria ram)

De ahi que al modificar una variable se "modifican" las dos: Se cambia el contenido en el cacillero de la memoria al cual apuntan las dos.

Última edición por wiwi74; 05/07/2010 a las 11:13
  #8 (permalink)  
Antiguo 05/07/2010, 14:41
 
Fecha de Ingreso: septiembre-2006
Mensajes: 68
Antigüedad: 18 años, 2 meses
Puntos: 0
Respuesta: Tratando de entender las referencias...

Gracias por el apunte, pero no es esa la lógica que no entiendo

Lo que no veo lógico es el comentario que pongo...
Código PHP:
$var 'foo';
function 
foo(&var){
    
$b 'baz';
    
$var =& $b// esto NO hace que $var sea 'baz' fuera de la función
// en cambio $var = $b; sí hace que $var pase a ser 'baz' fuera de la función
}
foo($var);
echo 
$var
Me lo creo, porque veo que funciona así y hay que aprenderlo así, pero no ayuda para nada a entenderlo

Es más, en php.net estoy viendo que ni siquiera haciendo dentro de la función un global $var vale, si no que además a $var hay que rebautizarla como $GLOBALS["var"]

Es decir...
Código PHP:
$var 'foo';
function 
foo(&$var){
    global 
$var;
    
$b 'baz';
    
$GLOBALS['var'] =& $b;
}
foo($var);
echo 
$var
Esto sí hace lo lógico (según mi manera de verlo, claro)
No sé si se me entiende demasiado bien
  #9 (permalink)  
Antiguo 05/07/2010, 14:51
Avatar de abimaelrc
Colaborador
 
Fecha de Ingreso: mayo-2009
Ubicación: En el planeta de Puerto Rico
Mensajes: 14.734
Antigüedad: 15 años, 5 meses
Puntos: 1517
Respuesta: Tratando de entender las referencias...

Te repito porque parece que no me leiste la primera vez. Eso sí hace referencia pero dentro la función y existe lo que se llama alcance de las variables (en ingles es variable scope). Si tu haces un echo a las variables dentro de la función vas a ver que sí hace referencia pero la referencia se hace dentro de la función y el alcance es interno solamente de la función. Si quieres que el alcance sea externo tienes que declararlo fuera de la función e indicar también en la función que hay al menos un argumento que lo vas a pasar por referencia.
__________________
Verifica antes de preguntar.
Los verdaderos amigos se hieren con la verdad, para no perderlos con la mentira. - Eugenio Maria de Hostos
  #10 (permalink)  
Antiguo 05/07/2010, 15:04
 
Fecha de Ingreso: septiembre-2006
Mensajes: 68
Antigüedad: 18 años, 2 meses
Puntos: 0
Respuesta: Tratando de entender las referencias...

Cita:
Iniciado por abimaelrc Ver Mensaje
Te repito porque parece que no me leiste la primera vez. Eso sí hace referencia pero dentro la función y existe lo que se llama alcance de las variables (en ingles es variable scope). Si tu haces un echo a las variables dentro de la función vas a ver que sí hace referencia pero la referencia se hace dentro de la función y el alcance es interno solamente de la función. Si quieres que el alcance sea externo tienes que declararlo fuera de la función e indicar también en la función que hay al menos un argumento que lo vas a pasar por referencia.
Sí que te leí
Y entiendo todo lo que dices, lo único que digo es que no me parece lógico por parte de quien se ha inventado ésto de las referencias (xD) que este código, tras modificar $var dentro de la función y estar $var pasada por referencia en la declaración de la función no tenga alcance externo

Código PHP:
$var 'foo';
$var2 'baz';
function 
foo(&$var,$var2){
    
$var =& $var2;
}
foo($var,$var2);
echo 
$var
Y este otro código, haciendo prácticamente lo mismo: modificar $var dentro de la función y estar $var pasada por referencia en la declaración de la función sí lo tenga

Código PHP:
$var 'foo';
$var2 'baz';
function 
foo(&$var,$var2){
    
$var $var2;
}
foo($var,$var2);
echo 
$var
  #11 (permalink)  
Antiguo 05/07/2010, 15:10
Avatar de abimaelrc
Colaborador
 
Fecha de Ingreso: mayo-2009
Ubicación: En el planeta de Puerto Rico
Mensajes: 14.734
Antigüedad: 15 años, 5 meses
Puntos: 1517
Respuesta: Tratando de entender las referencias...

Es que en el primer código estás creando la referencia dentro de la función y el segundo estás asignando un valor son dos cosas totalmente distintas. Entiendo que sí tiene sentido, solo que estás interpretando que hacer una referencia es declararla como global, es decir que todo el código debe interpretar la referencia estando fuera y adentro de la función y no así, por la razón del alcance de las variables. Puede que en un futuro tu hagas algún código que quieras que las variables tengan referencia dentro de la función pero que no se sepa fuera de ella las referencias (digo, no entiendo por qué harías esto, pero puede darse el caso ) al tener la regla del alcance de las variables se cumple. Si deseas que algo tenga alcance fuera debes declararlo forzosamente usando global (que creo que entiendes este concepto, solo lo doy por dato adicional).
__________________
Verifica antes de preguntar.
Los verdaderos amigos se hieren con la verdad, para no perderlos con la mentira. - Eugenio Maria de Hostos
  #12 (permalink)  
Antiguo 05/07/2010, 20:37
Avatar de wiwi74  
Fecha de Ingreso: marzo-2008
Mensajes: 515
Antigüedad: 16 años, 8 meses
Puntos: 10
Respuesta: Tratando de entender las referencias...

Redundando un poco:

Código PHP:

$var 
'foo';

function 
foo($var){

    
$b 'baz';
    
//le decimos a $var que apunte donde $b
    
$var =& $b;  
    
    
//la funcion devolvera 'baz'
    //$var desde dentro de la funcion no tiene valor propio, 
    //sino que solo APUNTA al valor de $b que es 'baz'
    //mediate return logramos sacarla fuera de la funcion, por asi decir.
    
return $var;
    
//Habra entonces dos variables $var
    //Una con valor propio
    //Y otra apuntando hacia el mismo valor que $b 'baz'
     
    //probamos modificar $var
    
$var "Esto no modifica a \$var";


}

echo 
"Valor por referencia de \$var: ".foo($var);
echo 
"<br />";

echo 
"Valor propio de \$var: ".$var;
echo 
"<br />"
  #13 (permalink)  
Antiguo 05/07/2010, 20:48
Avatar de wiwi74  
Fecha de Ingreso: marzo-2008
Mensajes: 515
Antigüedad: 16 años, 8 meses
Puntos: 10
Respuesta: Tratando de entender las referencias...

Y en el manual online quiza no encuentres esto (en español):

Lo que las Referencias no son

Como se ha mencionado antes, las Referencias NO son punteros. Esto significa que el siguiente ejemplo no hará lo que se espera:

Código PHP:

function foo (&$var)
{
    
$var =& $GLOBALS["baz"];
}
foo($bar); 

Lo que ocurrirá aquí es que $var en foo será 'ligada' con $bar al momento de llamar a la función. Pero luego será 're-ligada' con $GLOBALS["baz"]. No existe manera de ligar $bar en el ámbito global del script con alguna otra cosa utilizando el mecanismo de Referencias, ya que $bar no existe dentro de foo (está representado por $var, pero $var solo está ligado por el contenido, no por el nombre en la tabla de símbolos).


Otro ejemplo del manual:
Código PHP:

function foo (&$var)
{
    
$var++;
}

$a=5;
echo 
$a
foo
($a); 
//agregado: cuanto valdra $a ...?
echo "<br />".$a

What References Are Not:
http://www.php.net/manual/es/languag...nces.arent.php

Última edición por wiwi74; 05/07/2010 a las 21:02
  #14 (permalink)  
Antiguo 08/07/2010, 22:57
Avatar de mortiprogramador
Colaborador
 
Fecha de Ingreso: septiembre-2009
Ubicación: mortuoria
Mensajes: 3.805
Antigüedad: 15 años, 2 meses
Puntos: 214
Respuesta: Tratando de entender las referencias...

Hola falotron (se viene a colación los transformers)

bueno, no habia podido venir antes, pero veo que el tema
dio para buen hilo, y estan buenos los apuntes que te han dado

y pues tal vez sea un poco enredado el tema de las
referencias como ya has podido ver, asocialo a un truco de magia
donde tu muestras que algo aparece y desaparece, pero en realidad
lo que haces es ocultar algo y mostrar otra cosa, tal vez te has enredado
un poco pues generalmente es más usado el paso por valor, donde
si se modifican las variables directamente, esto de la referencia es,
como yo lo veo, para casos especificos donde necesites hacer uso
de la misma

jajaja, eso del truco de magia son demencias mias, espero no te
enrede mas

saludos
__________________
"Si consigues ser algo más que un hombre, si te entregas a un ideal, si nadie puede detenerte, te conviertes en algo muy diferente."
Visita piggypon.com
  #15 (permalink)  
Antiguo 09/07/2010, 03:28
 
Fecha de Ingreso: septiembre-2006
Mensajes: 68
Antigüedad: 18 años, 2 meses
Puntos: 0
Respuesta: Tratando de entender las referencias...

Jajajaja... sí, ya lo entendí... bueno, esa parte al menos

Hay otras partes que todavía no acabo de asimilarlas del todo, por ejemplo...

Código PHP:
<?php
function a($a$b) { 
$a $b
}
$a = new StdClass;
$a->1;
$b = new StdClass;
$b->2;
a($a$b);
$b->3;
print 
$a->i;
?>
En teoría este código equivale a hacer...

Código PHP:
<?php
$a 
1;
$b 2;
$a1 =& $a;
$b1 =& $b;
$a1 =& $b1;
$b 3;
print 
$a;
?>
Y esta explicación no la acabo de ver...
Entiendo que el código inicial devuelva 1, bueno, más que entenderlo es lo que esperaría, pero la explicación no la entiendo...

Está sacado de un comentario de la página
http://www.php.net/manual/en/languag...ences.pass.php
  #16 (permalink)  
Antiguo 09/07/2010, 08:05
Avatar de abimaelrc
Colaborador
 
Fecha de Ingreso: mayo-2009
Ubicación: En el planeta de Puerto Rico
Mensajes: 14.734
Antigüedad: 15 años, 5 meses
Puntos: 1517
Respuesta: Tratando de entender las referencias...

Lo que sucede es que en el primer ejemplo no haces referencia en ninguna parte. Solo asignas valores dentro de la función y esto no se refleja fuera de la función por lo que te había mencionado anteriormente. En realidad para que veas lo que hace la primera función hace algo similar a esto
Código PHP:
Ver original
  1. $a = 1;
  2. $b = 2;
  3.  
  4. $a1 = $a;
  5. $b1 = $b;
  6. $a1 = $b1;
  7.  
  8. $b = 3;
  9.  
  10. echo $a;
En realidad no hiciste cambio alguno a la variable $a que es la que estás imprimiendo.
__________________
Verifica antes de preguntar.
Los verdaderos amigos se hieren con la verdad, para no perderlos con la mentira. - Eugenio Maria de Hostos
  #17 (permalink)  
Antiguo 09/07/2010, 10:44
Avatar de mortiprogramador
Colaborador
 
Fecha de Ingreso: septiembre-2009
Ubicación: mortuoria
Mensajes: 3.805
Antigüedad: 15 años, 2 meses
Puntos: 214
Respuesta: Tratando de entender las referencias...

Hola
Bueno, revisando el link que dejaste, allí te muestran el porque te imprime 1, tienes que calmarte y leer pausadamente, si lo que quisieras es que en ese
print fuera un 2, entonces deberías modificar la función de este modo

Código PHP:
Ver original
  1. function a($a, $b) {
  2. $a->i = $b->i;
  3. }

pues en este punto ya no estas solo usando variable, sino ya estas usando
objetos de una clase, y por esto es necesario hacer uso de los mismos

espero te sirva, saludos
__________________
"Si consigues ser algo más que un hombre, si te entregas a un ideal, si nadie puede detenerte, te conviertes en algo muy diferente."
Visita piggypon.com

Etiquetas: entender, referencias
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

SíEste tema le ha gustado a 1 personas




La zona horaria es GMT -6. Ahora son las 16:43.