Delicious Bookmark this on Delicious Share on Facebook SlashdotSlashdot It! Digg! Digg



PHP : Language Reference : References Explained : What References Do

What References Do

PHP references allow you to make two variables to refer to the same content. Meaning, when you do:

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

it means that $a and $b point to the same content.

Note:

$a and $b are completely equal here, that's not $a is pointing to $b or vice versa, that's $a and $b pointing to the same place.

Note:

If array with references is copied, its values are not dereferenced. This is valid also for arrays passed by value to functions.

Note:

If you assign, pass or return an undefined variable by reference, it will get created.

Example 12.1. Using references with undefined variables

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

foo($a); // $a is "created" and assigned to null

$b = array();
foo($b['b']);
var_dump(array_key_exists('b', $b)); // bool(true)

$c = new StdClass;
foo($c->d);
var_dump(property_exists($c, 'd')); // bool(true)
?>


The same syntax can be used with functions, that return references, and with new operator (in PHP 4.0.4 and later):

<?php
$bar
=& new fooclass();
$foo =& find_var($bar);
?>

Since PHP 5, new return reference automatically so using =& in this context is deprecated and produces E_STRICT level message.

Note:

Not using the & operator causes a copy of the object to be made. If you use $this in the class it will operate on the current instance of the class. The assignment without & will copy the instance (i.e. the object) and $this will operate on the copy, which is not always what is desired. Usually you want to have a single instance to work with, due to performance and memory consumption issues.

While you can use the @ operator to mute any errors in the constructor when using it as @new, this does not work when using the &new statement. This is a limitation of the Zend Engine and will therefore result in a parser error.

Warning:

If you assign a reference to a variable declared global inside a function, the reference will be visible only inside the function. You can avoid this by using the $GLOBALS array.

Example 12.2. Referencing global variables inside function

<?php
$var1
= "Example variable";
$var2 = "";

function
global_references($use_globals)
{
   global
$var1, $var2;
   if (!
$use_globals) {
       
$var2 =& $var1; // visible only inside the function
   
} else {
       
$GLOBALS["var2"] =& $var1; // visible also in global context
   
}
}

global_references(false);
echo
"var2 is set to '$var2'\n"; // var2 is set to ''
global_references(true);
echo
"var2 is set to '$var2'\n"; // var2 is set to 'Example variable'
?>


Think about global $var; as a shortcut to $var =& $GLOBALS['var'];. Thus assigning other reference to $var only changes the local variable's reference.

Note:

If you assign a value to a variable with references in a foreach statement, the references are modified too.

Example 12.3. References and foreach statement

<?php
$ref
= 0;
$row =& $ref;
foreach (array(
1, 2, 3) as $row) {
   
// do something
}
echo
$ref; // 3 - last element of the iterated array
?>


The second thing references do is to pass variables by-reference. This is done by making a local variable in a function and a variable in the calling scope reference to the same content. Example:

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

$a=5;
foo($a);
?>

will make $a to be 6. This happens because in the function foo the variable $var refers to the same content as $a. See also more detailed explanations about passing by reference.

The third thing reference can do is return by reference.

Code Examples / Notes » language.references.whatdo

hlavac

Watch out for this:
foreach ($somearray as &$i) {
 // update some $i...
}
...
foreach ($somearray as $i) {
 // last element of $somearray is mysteriously overwritten!
}
Problem is $i contians reference to last element of $somearray after the first foreach, and the second foreach happily assigns to it!


amp

Something that might not be obvious on the first look:
If you want to cycle through an array with references, you must not use a simple value assigning foreach control structure. You have to use an extended key-value assigning foreach or a for control structure.
A simple value assigning foreach control structure produces a copy of an object or value. The following code
$v1=0;
$arrV=array(&$v1,&$v1);
foreach ($arrV as $v)
{
 $v1++;
 echo $v."\n";
}
yields
0
1
which means $v in foreach is not a reference to $v1 but a copy of the object the actual element in the array was referencing to.
The codes
$v1=0;
$arrV=array(&$v1,&$v1);
foreach ($arrV as $k=>$v)
{
$v1++;
echo $arrV[$k]."\n";
}
and
$v1=0;
$arrV=array(&$v1,&$v1);
$c=count($arrV);
for ($i=0; $i<$c;$i++)
{
$v1++;
echo $arrV[$i]."\n";
}
both yield
1
2
and therefor cycle through the original objects (both $v1), which is, in terms of our aim, what we have been looking for.
(tested with php 4.1.3)


dovbysh

Solution to post "php at hood dot id dot au 04-Mar-2007 10:56":
<?php
$a1 = array('a'=>'a');
$a2 = array('a'=>'b');
foreach ($a1 as $k=>&$v)
$v = 'x';
echo $a1['a']; // will echo x
unset($GLOBALS['v']);
foreach ($a2 as $k=>$v)
{}
echo $a1['a']; // will echo x
?>


joachim

So to make a by-reference setter function, you need to specify reference semantics _both_ in the parameter list _and_ the assignment, like this:
class foo{
  var $bar;
  function setBar(&$newBar){
     $this->bar =& newBar;
  }
}
Forget any of the two '&'s, and $foo->bar will end up being a copy after the call to setBar.


charles

points to post below me.
When you're doing the references with loops, you need to unset($var).
for example
<?php
foreach($var as &$value)
{
...
}
unset($value);
?>


php.devel

In reply to lars at riisgaardribe dot dk,
When a variable is copied, a reference is used internally until the copy is modified.  Therefore you shouldn't use references at all in your situation as it doesn't save any memory usage and increases the chance of logic bugs, as you discoved.


ladoo

I ran into something when using an expanded version of the example of pbaltz at NO_SPAM dot cs dot NO_SPAM dot wisc dot edu below.
This could be somewhat confusing although it is perfectly clear if you have read the manual carfully. It makes the fact that references always point to the content of a variable perfectly clear (at least to me).
<?php
$a = 1;
$c = 2;
$b =& $a; // $b points to 1
$a =& $c; // $a points now to 2, but $b still to 1;
echo $a, " ", $b;
// Output: 2 1
?>


php

I discovered something today using references in a foreach
<?php
$a1 = array('a'=>'a');
$a2 = array('a'=>'b');
foreach ($a1 as $k=>&$v)
$v = 'x';
echo $a1['a']; // will echo x
foreach ($a2 as $k=>$v)
{}
echo $a1['a']; // will echo b (!)
?>
After reading the manual this looks like it is meant to happen. But it confused me for a few days!
(The solution I used was to turn the second foreach into a reference too)


firespade

Here's a good little example of referencing. It was the best way for me to understand, hopefully it can help others.
$b = 2;
$a =& $b;
$c = $a;
echo $c;
// Then... $c = 2


Change Language


Follow Navioo On Twitter
What References Are
What References Do
What References Are Not
Passing by Reference
Returning References
Unsetting References
Spotting References
eXTReMe Tracker