Comunidad de diseño web y desarrollo en internet online

Variables por referencia y valor en PHP

¿Programaste en Pascal? Entonces, el término te puede sonar familiar.

¿Programaste en C? También, pero cuidado la referencia no son punteros, aunque en C las emulábamos así.

¿No has programado en ninguno? ¡Ja! Siento lástima por ti, programar en esos lenguajes es lo mejor. Aunque tengo tiempo que no los requiero y php para bien o para mal, ha sido mi fiel compañero desde hace años. ¡Nostalgia, vete de aquí!

Referencias


Llamamos referencia en php a la capacidad de otorgarles varios nombres de variable al mismo contenido, para lograr esto tenemos el operador &.

Ejemplo:

Código :

<?php
   $a = 5;
   $b =& $a;
   $b = 6;
?>

En este código, al contenido (5) de la variable $a le damos otro nombre ($b). Por esto, cuando ejecutamos la asignación de $b, $a también cambiará su valor a 6.

Demostración:

Código :

<?php 
   $a = 5;
   $b =& $a;
   $b = 6;

   echo "a: ";
   var_dump($a);
   echo "b: ";
   var_dump($b);
?>


Salida:
a: int(6)
b: int(6)


Ahora, como dije anteriormente, las referencias NO son punteros. Es mejor pensar como las referencias como link a una web. Puede haber indecibles link's apuntando a cristalab, si cristalab cambia su contenido, todos los links apuntarian al nuevo contenido.

Demostración de que las referencias NO son punteros:

Código :

<?php
   $a = 5;
   $b =& $a;
   $b = 6;

   echo "a: ";
   var_dump($a); 
   echo "b: ";
   var_dump($b);

   // destruyendo $a, "liberando memoria"
   unset($a);
   echo 'Se ejecutó unset($a)';
   echo "a: ";
   var_dump($a);
   echo "b:";
   var_dump($b);
?>

Salida:
a: int(6)
b: int(6)
Se ejecutó unset($a)
a: NULL
b: int(6)


Si $b fuera puntero, también se destruyera y perdería su valor. Así que, repitan conmigo: "¡Las referencias NO son punteros!"


Retorno por Referencia


Una función también puede retornar una referencia de una variable que tenga en su ámbito, para lograr esto el operador &, debe estar presente en el nombre de la función y en la asignación.

Nota: para que los desconocen 'static', en el ámbito de funciones hace que la variable se inicialice en la primera invocación de la función.


Ejemplo:

Código :

<?php 
   function &unaFuncion()
   {
      static $var =0;
      echo "var: ";
      var_dump($var);
      return $var;
   }

   $alias =& unaFuncion();

   echo "alias: ";
   var_dump($alias);
   $alias++;
   unaFuncion();
   echo "alias: ";
   var_dump($alias);
?>

Salida:

var: int(0);
alias: int(0);
var: int(1);
alias: int(1);


Parámetros por referencia


Los parámetros, es un poco 'diferente' que las funciones. Puesto que, el operador (&) puede estar en la definición del parámetro de la función, o en la invocación de la función y pasar una variable por referencia como parámetro.

Ejemplo:

Código :

<?php
   function miFuncion (&$a) 
   { 
      return ++$a;  
   } 
    
   function otraFuncion ($a) 
   { 
      return ++$a; 
   } 
    
   $param = 0; 
   echo 'miFuncion($param): ';  
   miFuncion($param); 
   var_dump($param); 
    
   $variable = 0; 
    
   echo 'otraFuncion(&$variable): ';  
   otraFuncion(&$variable); 
   var_dump($variable);
?>


Salida:
miFuncion($param): int(1)
otraFuncion($variable): int(1)


En verdad, no es que haya dos formas. Solo en la primera función (miFuncion) existe parámetro por referencia; en la segunda, en verdad, es como si hiciéramos $a =& $variable.

Nota: cuando un parámetro es definido por referencia, solo puedes pasarle variables, constantes NO. Así que miFuncion(1); provocaría un error fatal.

Referencias en Clases. ¡Cuidado!


En las clases también hacer uso de referencias, pero debes tener cuidado. Revisemos esto:

Código :

<?php

class MyClass
{
   private $prop;
   
   public function __construct()
   {
      $this->prop =0;
   }
   
   public function &metodo()
   {
      return $this->prop;
   }
}

$instancia = new MyClass();

echo $instancia->metodo();

$variable = $instancia->metodo();

$variable++;

echo $instancia->metodo(); // ¡Rayos! cambiamos la propiedad privada!!
?>

Salida:
0
1


Como ven deben tener cuidado a usarlo en las clases, porque al hacerlo con propiedades private o protected, que por definición no pueden modificarse fuera de las clases. Con referencias lo pudieran hacer y esto podría traer serios problemas al tratar de controlar el acceso a ella.

Conclusión


Las referencias pueden ser muy útiles y a veces ayudan, incluso a reducir lineas de código (Les dejo la tarea demostrarlo). Sin embargo, deben ser usadas con conciencia, su uso indiscriminado es evidencia de falla de lógica de programación.

¿Sabes SQL? ¿No-SQL? Aprende MySQL, PostgreSQL, MongoDB, Redis y más con el Curso Profesional de Bases de Datos que empieza el martes, en vivo.

Publica tu comentario

o puedes...

¿Estás registrado en Cristalab y quieres
publicar tu URL y avatar?

¿No estás registrado aún pero quieres hacerlo antes de publicar tu comentario?

Registrate