search for in the  
<What References Are NotReturning References>
Last updated: Thu, 19 May 2005

Passing by Reference

You can pass variable to function by reference, so that function could modify its arguments. The syntax is as follows:

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

$a=5;
foo($a);
// $a is 6 here
?>

Note that there's no reference sign on function call - only on function definition. Function definition alone is enough to correctly pass the argument by reference.

Following things can be passed by reference:

  • Variable, i.e. foo($a)

  • New statement, i.e. foo(new foobar())

  • Reference, returned from a function, i.e.:

    <?php
    function &bar()
    {
      
    $a = 5;
       return
    $a;
    }
    foo(bar());
    ?>

    See also explanations about returning by reference.

Any other expression should not be passed by reference, as the result is undefined. For example, the following examples of passing by reference are invalid:

<?php
function bar() // Note the missing &
{
  
$a = 5;
   return
$a;
}
foo(bar());

foo($a = 5); // Expression, not variable
foo(5); // Constant, not variable
?>

These requirements are for PHP 4.0.4 and later.



User Contributed Notes
Passing by Reference
mogmios at mlug dot missouri dot edu
11-May-2005 12:33
References don't seem to work correctly with objects. I don't seem to be able to nest objects such that each child has a reference to it's parent.

The below seems to not work.

class tree {
  var $parentNode;
  var $childNodes;
  function tree ( &$parentNode = None ) {
   $this->parentNode =& $parentNode;
  }
}
$parent = new tree ();
$child = new tree ( $parent );
pillepop2003 at yahoo dot de
13-Feb-2005 10:08
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!
obscvresovl at NOSPAM dot hotmail dot com
26-Dec-2004 12:51
Just a simple note...

<?

$num
= 1;

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

blah($num);

echo
$num; #2

?>

<?

$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.
jbr at diasparsoftware dot com
28-Sep-2004 11:46
Strangely enough, I had to put "&" on the call site, but not on the function parameter list, in order to get this to work. Here is the code:

<?php
class TestRunner {
   var
$passed;
   var
$failed;
   var
$tests;
  
   function
TestRunner() {
      
$this->passed = 0;
      
$this->failed = 0;
      
$this->tests = array();
   }

   function
addTest($test) {
      
$this->tests[] = $test;
   }

   function
signalFailed() {
      
$this->failed++;
   }
      
   function
runTests() {
       foreach (
$this->tests as $i => $eachName) {
          
call_user_func($eachName, &$this);
       }
   }
      
   function
report() {
      
?>
        <p><?= count($this->tests) ?> run, <?= $this->passed ?> passed, <?= $this->failed ?> failed</p>       
       <?php
  
}
}

function
testNullStringIsEmpty($testRunner) {
  
$testRunner->signalFailed();
}

$testRunner = new TestRunner;
$testRunner->addTest("testNullStringIsEmpty");
$testRunner->runTests();
$testRunner->report();
?>

Notice that testNullStringIsEmpty() does not declare that it wants a reference to a test runner, whereas on the function call site, we pass in &$this. When I run this, I get "1 run, 0 passed, 1 failed"; but when I switch the location of the & to the function parameter list, I get "1 run, 0 passed, 0 failed". This is the exact opposite to what the manual claims. I have no idea why that is.
Sergio Santana: ssantana at tlaloc dot imta dot mx
10-Sep-2004 10:25
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.

<?
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.
ben at mekhaye dot net
01-Sep-2004 04:27
Passing arrays by reference doesn't work as I expected from within call_user_func.

I had:

  <?
  $arr
= Array();
 
call_user_func(Array("ClassName","functionName"), $param1, $param2, $arr);
 
print_r($arr);

  class
ClassName {

    
functionName($param1, $param2, &$arr) {
      
$arr[0] = "apple";
      
$arr[1] = "banana";
      
print_r($arr);
     }
  }
 
?>

I expected the output to be like:

  Array ( [0] => "apple" [1] => "banana" )
  Array ( [0] => "apple" [1] => "banana" )

but instead it was only:

  Array ( [0] => "apple" [1] => "banana" )

However, when I changed the function call to plain old:

  <?
  $arr
= Array();
 
ClassName::functionName($param1,$param2,$arr);
 
print_r($arr);
 
?>

Output was the expected:

  Array ( [0] => "apple" [1] => "banana" )
  Array ( [0] => "apple" [1] => "banana" )
php at meKILLTHIStatoandthisols dot org
09-Jun-2004 02:33
Ever been in a situation where you have to write:

  <?php
   $t
= 1 ;
  
$x =& $t ;
 
?>

or

  <?php
   $t
= 1 ;
  
f( $t ) ;
 
?>

because you cannot pass constants by value. The function

  <?php
  
function& pclone( $v ) {
     return(
$v ) ;
   }
 
?>

lets you get ridd of the temporary variable. You can write:

  <?php
   $x
=& pclone( 1 ) ;
 
?>

or

  <?php
   f
( pclone( 1 ) ) ;
 
?>

Alternatively you can use the other alternative ;-)
blistwon-php at designfridge dot com
17-Jan-2004 08:33
One thing to note about passing by reference. If you plan on assigning the reference to a new variable in your function, you must use the reference operator in the function declaration as well as in the assignment. (The same holds true for classes.)

-------------------------------------------------------
CODE
-------------------------------------------------------
function f1(&$num) {
   $num++;
}
function f2(&$num) {
   $num1 = $num;
   $num1++;
}
function f3(&$num) {
   $num1 = &$num;
   $num1++;
}

$myNum = 0;
print("Declare myNum: " . $myNum . "<br />\n");
f1($myNum);
print("Pass myNum as ref 1: " . $myNum . "<br />\n");
f2($myNum);
print("Pass myNum as ref 2: " . $myNum . "<br />\n");
f3($myNum);
print("Pass myNum as ref 3: " . $myNum . "<br />\n");
-------------------------------------------------------

-------------------------------------------------------
OUTPUT
-------------------------------------------------------
 Declare myNum: 0
 Pass myNum as ref 1: 1
 Pass myNum as ref 2: 1
 Pass myNum as ref 3: 2
-------------------------------------------------------

Hope this helps people trying to detangle any problems with pass-by-ref.

<What References Are NotReturning References>
 Last updated: Thu, 19 May 2005
Copyright © 2001-2005 The PHP Group
All rights reserved.
This unofficial mirror is operated at: The Server Pages
Last updated: Thu May 19 17:35:34 2005 CDT