Foros del Web » Programando para Internet » PHP »

Paso de parámetros por referencia

Estas en el tema de Paso de parámetros por referencia en el foro de PHP en Foros del Web. Holas. Llevo un tiempo como visitante en el foro y porfin he decidido registrarme :) Bueno, a lo que voy... El problema que está a ...
  #1 (permalink)  
Antiguo 18/08/2005, 18:19
 
Fecha de Ingreso: agosto-2005
Mensajes: 143
Antigüedad: 12 años, 3 meses
Puntos: 0
Paso de parámetros por referencia

Holas.
Llevo un tiempo como visitante en el foro y porfin he decidido registrarme :)

Bueno, a lo que voy...
El problema que está a la hora de comprender las referencias.

Antes de seguir quiero saber si tengo los conceptos claros(que puede que aquí esté mi error). Espero saber explicarme.
Código PHP:
<?php
$a 
=& $b;
?>
En este caso $a y $b apuntan al mismo sitio de memoria ¿no?

Bueno. Donde realmente creo que tengo el problema de comprensión es en el paso de parametros por referencia.
Este es el punto que me gustaría que me explicarais :)

Pongo como yo creo que funciona esto:
Código PHP:
<?php
function algo($var)
{
    
$var++;
}
$a 5;
echo 
algo($a);
?>
Aqui no pasamos por referencia y lo que yo creo que pasa es que imprime en pantalla 6 pero la variable $a sigue valiendo 5;
Para todo esto se supone que en memoria se ocupa mas espacio que si lo hacemos por referencia. Por que la funcion algo() tiene una variable local que almacena el dato que le pasamos y realiza una operación con el y ese valor que le datos tiene que estar en alguna parte.
Entonces pienso que al pasarlo por referencia lo que hacemos esque esa función no cree la variable $var para realizar las operaciones sino que use la memoria en la que esta almacenado el valor de $a.

¿Se me ha entendido lo que quiero decir? Estoy en lo cierto ¿no?

Con lo cual en el script siguiente se usaria menos memoria y realizaria la misma función que el anterior(si no me equivoco)
Código PHP:
<?php
function algoref(&$var)
{
    
$var++;
}
$a 5;
echo 
algoref($a);
?>
Eso es una buena explicación para que $a despues de pasarle la función algoref() tenga el valor de 6. PORQUE LA FUNCION HA ESCRITO EN LA MEMORIA DE $a Y NO HA CREADO OTRA VARIABLE!!! xDD
Asi es como creo que esto funciona.

Mi duda es si estoy en lo cierto ¿?


Siento escribir un tema tan largo pero esque requiere una explicación completa por mi parte. Creo que en este foro hay gente que seguro que sabe responderme a mis preguntas :)

Gracias por leerlo y espero alguna respuesta :)
  #2 (permalink)  
Antiguo 18/08/2005, 18:46
 
Fecha de Ingreso: junio-2002
Mensajes: 243
Antigüedad: 15 años, 6 meses
Puntos: 1
Hay una cosilla q está mal...

como la funcion no devuelve nada...

lo q deberias hacer es lo sigueinte

Código PHP:
<?php 
function algoref(&$var

    
$var++; 

$a 5
algoref($a); 
echo 
$a;
?>
también es equivalente poner el & cuando llamas a la función...q es lo q por lo menos yo solia hacer en c

Código PHP:
<?php 
function algoref($var

    
$var++; 

$a 5
algoref(&$a); 
echo 
$a;
?>
en ambos casos la salida será 6

Con respecto a lo de la memoria pues si solo hay una posicion de memoria para ambas varaibles osease q ambas varaibles apuntan a la misma posición de memoria...

pero la verdad es q se suele usar poco ya q hay q tener mucho cuidad con no cargarse varaibles q no se deben...y a veces es mejor ocupar un poco más de memoria...

de todos modos creo q es mejor programar pasando por valor y mirar de liberar memoria por otros lados como en consultas mysql utilizar mysql_free_result...

Salu2.
  #3 (permalink)  
Antiguo 19/08/2005, 06:41
 
Fecha de Ingreso: agosto-2005
Mensajes: 143
Antigüedad: 12 años, 3 meses
Puntos: 0
Retorno por referencia

Muchas gracias por leerte el post lotusxxl.

Bueno si olvide el return :)

Pero claro, no quise ponerlo porque la siguiente pregunta es la de retorno por referencia y no sabia si iba a complicar la explicación con eso.

Este es la parte de la que no entiendo nada(retorno por referencia). No sabría poner un ejemplo porque esque no lo comprendo.
Al igual que no comprendo como funcionaria las referencias en una clase.
Código PHP:
<?php
//un ejemplo un poko rapido;
class algo
{
    var 
$Nombre;

    function &
iniciar()
    {
        static 
$a;
        if(isset(
$a))
        {
            
$a = new algo;
        }
        return 
$a;
    }
    function 
getnombre()
    {
        
//etc
        
return $this->Nombre;
    }
    
//.....
    //....
}

$algo =& algo::iniciar();
echo 
$algo->getNombre();
?>
No se , es un ejemplo rapido...por ejemplo: devería declarar getNombre() con & delante?...usar eso con clases sirvepara ahorrar memoria¿?

Siento no poder explicarme mejor, pero esque esta parte no la comprendo. No se si iniciar() lo que hace es crear la instancia en la memoria que tiene $algo(del script) reservada...

Se que normalmente no se usa...pero no esta mal saberlo por si en un momento dado hace falta implementarlo.

Gracias de nuevo por todo...espero alguna ayudita :)
  #4 (permalink)  
Antiguo 19/08/2005, 07:23
 
Fecha de Ingreso: junio-2002
Mensajes: 243
Antigüedad: 15 años, 6 meses
Puntos: 1
Creo q es mejor q preguntes en la sección de POO

yo esto de las clases de c++ las tengo un poco oxidadas...

en php he hecho algo pero cosas muy sencillas

siento no poder ayudarte.

Salu2.
  #5 (permalink)  
Antiguo 19/08/2005, 07:40
 
Fecha de Ingreso: agosto-2005
Mensajes: 143
Antigüedad: 12 años, 3 meses
Puntos: 0
De acuerdo. Gracias por responder...preguntare en POO.

Solo una última cosa(que seguro que sabes xD)
Es en retorno por referencia. No consigo encontrar la lógica a este código por ejemplo:
Código PHP:
<?php
function &retref($var)
{
    
$var += 1;
    return 
$var;
}

$a 5;
$a =& retref($a);
echo 
$a;
?>
¿Donde esta el ahorro de memoria aquí?
La función retref() creará una variable $var con lo cual no hay ahorro de memoria ¿no?

No se...llevo dándole vueltas algunos dias y estoy echo un lio. No se si podrás explicarme o a lo mejor te resulta más fácil explicarmelo con un ejemplo en C++.

Bueno, yo planteo el problema por si alguien sabe responder. Gracias de todas maneras :)
  #6 (permalink)  
Antiguo 19/08/2005, 11:34
 
Fecha de Ingreso: junio-2002
Mensajes: 243
Antigüedad: 15 años, 6 meses
Puntos: 1
Pues me parece que lo q has escrito está mal..

te da el mismo resultado pero si te fijas no estás referenciando la varaible $a

lo q estas haciendo es llamar a una función q devuelve un valor y luego se lo asignas a $a

pero si en vez de asignarlo a $a se lo asignas a por ejemplo $b y luego imprimes $a entonces te devolverá 5 en vez de 6...

Código PHP:
function &retref($var

    
$var += 1
    return 
$var


$a 5
$b =& retref($a); 
echo 
$a
PHP creo q a veces tiene un compilador demasiado poco sensible...c es más estricto...y no te deja poner & donde te plazca...

en este ejemplo no te da ningún error pero no se yo si es un buen modo de programar...

creo q el modo de hacerlo correctamente por lo menos desde el punto de vista de c sería el siguiente...

Código PHP:
function retref($var

    
$var += 1
    return 
$var


$a 5
$b retref(&$a); 
echo 
$a
en
Código PHP:
return $var
lo q en realdiad devuelves es el valor q hay en la posición de memoria de $a

Espero q te haya aclarado algo..pq no se q decrite ya jeje

Salu2.
  #7 (permalink)  
Antiguo 19/08/2005, 12:10
 
Fecha de Ingreso: agosto-2005
Mensajes: 143
Antigüedad: 12 años, 3 meses
Puntos: 0
Bueno Lotus, muchas gracias por el interés :)

He comprendido bien el paso por referencia pero no consigo entender el retorno por referencia. No le veo la lógica ni el uso que puede sacarse de él.

Aún así dejo el link a la parte del manual oficial de PHP que habla sobre eso, por si alguien consigue sacar algo en claro:
http://www.php.net/manual/es/languag...ces.return.php

Gracias de todas maneras, seguiré mirando codigos y probando cosas. Si encuentro el sentido ya lo postearé aquí :)
  #8 (permalink)  
Antiguo 19/08/2005, 13:42
 
Fecha de Ingreso: junio-2002
Mensajes: 243
Antigüedad: 15 años, 6 meses
Puntos: 1
Bueno he estado leyendo la documentación de php...algo escasa..

también he enocntrado uan web q habla de esto...en c

http://www.zator.com/Cpp/E4_4_7.htm

pero tampoco saco mucho en claro...

no le veo mucha utilidad a devolver por referencia..ya q cuando termina la función las varaibles se sacan de la pila..así q...

solo hay un casoen q tb han hecho ejemplos...q es en usar una varaible global y devolverla por referencia...

osease a mi entender devolver por referencia es viene a ser pasar variable por referencia pero en sentido inverso...

pongo aquí un ejemplo modificado q hay en la web oficial...

y lo máximo q he podido llegar a entender...

Código PHP:
$a=1;
function &
foo()
{
  global 
$a;
  return 
$a;
}
$b=&foo();
echo 
$b;  // shows 1
$b=2;
echo 
$a// shows 2 
podemos apreciar q foo devuelve la referencia de la varaible $a...entonces $b está referenciada a la misma posición de memoria q $a.

ya no doy más de si xD.

Salu2.
  #9 (permalink)  
Antiguo 19/08/2005, 18:05
 
Fecha de Ingreso: agosto-2005
Mensajes: 143
Antigüedad: 12 años, 3 meses
Puntos: 0
jejejje, gracias por el interés lotus :))

Esto no tiene más sitios por donde agarrarlo así que parece que es eso..porque yo tampoco doy mas de si xDD.

Otra cosa graciosa que he leido es que en algunos caso el referenciar a una variable retarda la ejecución del script y merece más la pena crear otra variable xDD.

De nuevo...gracias por el interés (Y). Aunque no lo use mucho por lo menos ya lo tengo claro :)
  #10 (permalink)  
Antiguo 19/08/2005, 22:10
Avatar de jpinedo
Colaborador
 
Fecha de Ingreso: septiembre-2003
Ubicación: Lima, Perú
Mensajes: 3.120
Antigüedad: 14 años, 2 meses
Puntos: 41
Hola:
La utilidad del retorno por referencia es más clara cuando se manejan objetos y no variables simples.

Te pongo un ejemplo:
Código PHP:
<?php
class A{
    var 
$nombre "porDefecto";
}

class 
B{
    var 
$componenteDeB;
    
    function 
B(&$comp){//constructor
        
$this->componenteDeB = &$comp;
    }

    function 
cambiarNombreDeComponenteDeB($nuevoNombre){
        
$componente = &$this->componenteDeB;
        
$componente->nombre $nuevoNombre;
    }

    function & 
obtenerComponenteDeB(){
        return 
$this->componenteDeB;
    }

    function 
obtenerNombreDeComponenteDeB(){
        
$componente $this->componenteDeB;
        return 
$componente->nombre
    }
}

class 
C{
    var 
$componenteDeC;
    
    function 
C(&$comp){//constructor
        
$this->componenteDeC = &$comp;
    }

    function 
cambiarNombreDeComponenteDeC($nuevoNombre){
        
$componente = &$this->componenteDeC;
        
$componente->nombre $nuevoNombre;
    }
}


// Creamos un objeto B, pasando como parámetro un nuevo objeto A como componente:
$objetoB = new B(new A);
// Cambiamos el nombre de su componente:
$objetoB->cambiarNombreDeComponenteDeB('nombre1');

// Ahora creamos un objeto C pero queremos que comparta la componente con B:
// O sea, le pasamos como parámetro la componente de B, pero será una referencia, ya que ese método obtenerComponenteDeB() está declarado para que devuelva una referencia.
$objetoC = new C($objetoB->obtenerComponenteDeB());
// Cambiamos el nombre de su componente:
$objetoC->cambiarNombreDeComponenteDeC('nombre2');

// Vemos cuál es el valor del nombre en la componente de B
echo $objetoB->obtenerNombreDeComponenteDeB();// esto imprime 'nombre2'
?>
Mira todo el manejo de referencias y espero que tengas muchas preguntas.

Lo que no se debe hacer es:
- Si queremos que "unaFuncion()" maneje una referencia de $variable como parámetro:
Código PHP:
// INCORRECTO
function unaFuncion($unParametro){
   
// acciones
}

unaFuncion(&$variable); 
Código PHP:
// CORRECTO
function unaFuncion(&$unParametro){
   
// acciones
}

unaFuncion($variable); 
Saludos
  #11 (permalink)  
Antiguo 20/08/2005, 04:31
 
Fecha de Ingreso: agosto-2005
Mensajes: 143
Antigüedad: 12 años, 3 meses
Puntos: 0
WOW!!

Muchas gracias jpinedo eso es lo que iba a preguntar en POO(cuando me aclarara un poco)

Ahoramismo no estoy preparado para "meterme eso en la cabeza"(estamos en feria en Málaga xD) pero cuando descanse un poco prometo que me pondré a saco y te pasaré mi lista de preguntas :))

AH!!, lo segundo que has dicho..si ya lo sabia...cuando lo hice como se haría en C me salto un warning, creo recordar, que me decia que tenía que hacerlo en la declaración de la función.

Gracias de nuevo a los ods por el interés mostrado.
  #12 (permalink)  
Antiguo 20/08/2005, 07:01
 
Fecha de Ingreso: agosto-2005
Mensajes: 143
Antigüedad: 12 años, 3 meses
Puntos: 0
Bueno, pues muchas gracias...creo que es lo que me hacia falta.

Creo que lo he pillado todo(raro en mi xD).

Saludos ;)
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 07:00.