Pasar por Referencia

Se puede pasar una variable por referencia a una función y así hacer que la función pueda modificar la variable. La sintaxis es la siguiente:

<?php
function foo(&$var)
{
    
$var++;
}

$a=5;
foo($a);
// $a es 6 aquí
?>

Nota: No existe ningún signo de referencia en una llamada a una función - sólo en la definición de la función. Las definiciones de funciones por sí solas son suficientes para pasar correctamente el argumento por referencia. A partir de PHP 5.3.0, se obtendrá una advertencia diciendo que "call-time pass-by-reference" (pasar por referencia en tiempo de llamada) está obsoleto cuando se use & en foo(&$a);. A partir de PHP 5.4.0, el paso por referencia en tiempo de llamada ha sido eliminado, por lo que su uso emitirá un error fatal.

Se puede pasar por referencia lo siguiente:

  • Variables, esto es, foo($a)
  • Nuevas declaraciones, esto es, foo(new foobar())
  • Referencias devueltas desde funciones, esto es:

    <?php
    function foo(&$var)
    {
        
    $var++;
    }
    function &
    bar()
    {
        
    $a 5;
        return 
    $a;
    }
    foo(bar());
    ?>
    Vea más sobre devolver por referencia.

Ninguna otra expresión debería pasarse por referencia, ya que el resultado no está definido. Por ejemplo, los siguientes ejemplos de pasar por referencia no son válidos:

<?php
function foo(&$var)
{
    
$var++;
}
function 
bar() // Observe que falta el &
{
    
$a 5;
    return 
$a;
}
foo(bar()); // Produce un error fatal a partir de PHP 5.0.5

foo($a 5); // Expresión, no una variable
foo(5); // Produce un error fatal
?>
Estos requerimientos son para PHP 4.0.4 y posterior.

add a note add a note

User Contributed Notes 6 notes

up
6
diabolos @t gmail dot com
1 year ago
<?php

/*

  This function internally swaps the contents between
  two simple variables using 'passing by reference'.

  Some programming languages have such a swap function
  built in, but PHP seems to lack such a function.  So,
  one was created to fill the need.  It only handles
  simple, single variables, not arrays, but it is
  still a very handy tool to have.

  No value is actually returned by this function, but
  the contents of the indicated variables will be
  exchanged (swapped) after the call.
*/

// ------------------------------------------
// Demo call of the swap(...) function below.

 
$a = 123.456;
 
$b = 'abcDEF';
 
 print
"<pre>Define:\na = $a\nb = '$b'</pre>";
 
swap($a,$b);
 print
"<pre>After swap(a,b):\na = '$a'\nb = $b</pre>";

// -------------------------------

  
function swap (&$arg1, &$arg2)
{

// Swap contents of indicated variables.
  
$w=$arg1;   $arg1=$arg2;   $arg2=$w;
}

?>
up
2
pillepop2003 at yahoo dot de
9 years ago
PHP has a strange behavior when passing a part of an array by reference, that does not yet exist.

<?php
   
function func(&$a)
    {
       
// void();
   
}
   
   
$a['one'] =1;
   
func($a['two']);
?>   

var_dump($a) returns

    array(2) {
        ["one"]=>
        int(1)
        ["two"]=>
        NULL
    }

...which seems to be not intentional!
up
1
obscvresovl at NOSPAM dot hotmail dot com
9 years ago
Just a simple note...

<?php

$num
= 1;

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

blah($num);

echo
$num; #2

?>

<?php

$num
= 1;

function
blah()
{
   
$var =& $GLOBALS["num"];
   
$var++;
}

blah();

echo
$num; #2

?>

Both codes do the same thing! The second code "explains" how passage of parameters by reference works.
up
0
phpnet at holodyn dot com
23 days ago
The notes indicate that a function variable reference will receive a deprecated warning in the 5.3 series, however when calling the function via call_user_func the operation aborts without fatal error.

This is not a "bug" since it is not likely worth resolving, however should be noted in this documentation.
up
0
fdelizy at unfreeze dot net
7 years ago
Some have noticed that reference parameters can not be assigned a default value. It's actually wrong, they can be assigned a value as the other variables, but can't have a "default reference value", for instance this code won't compile :

<?php
function use_reference( $someParam, &$param =& $POST )
{
 ...
}
?>

But this one will work :

<?php
function use_reference( $someParam, &$param = null )
?>

So here is a workaround to have a default value for reference parameters :

<?php
$array1
= array ( 'test', 'test2' );

function
AddTo( $key, $val, &$array = null)
{
    if (
$array == null )
    {
     
$array =& $_POST;
    }

   
$array[ $key ] = $val ;
}

AddTo( "indirect test", "test", $array1 );
AddTo( "indirect POST test", "test" );

echo
"Array 1 " ;
print_r ( $array1);

echo
"_POST ";
print_r( $_POST );

?>

And this scripts output is :

Array 1 Array
(
    [0] => test
    [1] => test2
    [indirect test] => test
)
_POST Array
(
    [indirect POST test] => test
)

Of course that means you can only assign default reference to globals or super globals variables.

Have fun
up
0
Sergio Santana: ssantana at tlaloc dot imta dot mx
9 years ago
Sometimes we need functions for building or modifying arrays whose elements are to be references to other variables (arrays or objects for instance). In this example, I wrote two functions 'tst' and 'tst1' that perform this task. Note how the functions are written, and how they are used.

<?php
function tst(&$arr, $r) {
 
// The argument '$arr' is declared to be passed by reference,
  // but '$r' is not;
  // however, in the function's body, we use a reference to
  // the '$r' argument
 
 
array_push($arr, &$r);
 
// Alternatively, this also could be $arr[] = &$r (in this case)
}
 
$arr0 = array();          // an empty array
$arr1 = array(1,2,3);   // the array to be referenced in $arr0

// Note how we call the function:
tst($arr0, &$arr1); // We are passing a reference to '$arr1' in the call !

print_r($arr0); // Contains just the reference to $arr1

array_push($arr0, 5); // we add another element to $arr0
array_push($arr1, 18); // we add another element to $arr1 as well

print_r($arr1); 
print_r($arr0); // Changes in $arr1 are reflected in $arr0

// -----------------------------------------
// A simpler way to do this:

function tst1(&$arr, &$r) {
 
// Both arguments '$arr' and '$r" are declared to be passed by
  // reference,
  // again, in the function's body, we use a reference to
  // the '$r' argument
 
 
array_push($arr, &$r);
 
// Alternatively, this also could be $arr[] = &$r (in this case)
}

 
$arr0 = array();          // an empty array
$arr1 = array(1,2,3);   // the array to be referenced in $arr0

// Note how we call the function:
tst1($arr0, $arr1); // 'tst1' understands '$r' is a reference to '$arr1'

echo "-------- 2nd. alternative ------------ <br>\n";

print_r($arr0); // Contains just the reference to $arr1

array_push($arr0, 5); // we add another element to $arr0
array_push($arr1, 18);

print_r($arr1); 
print_r($arr0); // Changes in $arr1 are reflected in $arr0

// This outputs:
// X-Powered-By: PHP/4.1.2
// Content-type: text/html
//
// Array
// (
//     [0] => Array
//         (
//             [0] => 1
//             [1] => 2
//             [2] => 3
//         )
//
// )
// Array
// (
//     [0] => 1
//     [1] => 2
//     [2] => 3
//     [3] => 18
// )
// Array
// (
//     [0] => Array
//         (
//             [0] => 1
//             [1] => 2
//             [2] => 3
//             [3] => 18
//         )
//
//     [1] => 5
// )
// -------- 2nd. alternative ------------
// Array
// (
//     [0] => Array
//         (
//             [0] => 1
//             [1] => 2
//             [2] => 3
//         )
//
// )
// Array
// (
//     [0] => 1
//     [1] => 2
//     [2] => 3
//     [3] => 18
// )
// Array
// (
//     [0] => Array
//         (
//             [0] => 1
//             [1] => 2
//             [2] => 3
//             [3] => 18
//         )
//
//     [1] => 5
// )
?>

In both cases we get the same result.

I hope this is somehow useful

Sergio.
To Top