search for in the  
<ExceptionsWhat References Do>
Last updated: Thu, 19 May 2005

Chapter 21. References Explained

What References Are

References in PHP are a means to access the same variable content by different names. They are not like C pointers, they are symbol table aliases. Note that in PHP, variable name and variable content are different, so the same content can have different names. The most close analogy is with Unix filenames and files - variable names are directory entries, while variable contents is the file itself. References can be thought of as hardlinking in Unix filesystem.



User Contributed Notes
References Explained
rlynch at lynchmarks dot com
17-May-2005 05:51
And, further...

<?php
   $intSize
= sizeof($arrData);

   for(
$i = 0; $i < $intSize; $n++) {
      
// Do stuff
  
}
?>

Can be shortened even further by using the often overlooked 'decrement until zero' concept.  I don't much like decrementing to get a job done, but it can make a lot of sense when the evaluation-of-doneness is time-costly:

<?php
  
for($i = sizeof($arrData); $i-- > 0 ; ) {
      
// Do stuff 
  
}
?>

One less variable to toss on the heap.  NOTE that rather inconveniently, the $i goes to and hits zero only in the case where it starts out positive.  When it is zero to begin with, it will become -1.  Bug or feature?  I've used it as a feature as a quick test of whether the $arrData array was empty to begin with.  If you don't plan on using $i after the loop for anything, it makes no difference.

If you need to be doing something ascending-sequential though, then the temporary variable suggestions that others have made makes the most sense.

Finally (and important) ... if the $arrData array is somehow being dynamically modified in size due to the //Do-Stuff routine underneath, then you may have little-to-no recourse except to use the sizeof() method/function in the loop.  Or, keep up the temporary variable in the loop as you push and pop things into and off the array. 

(sigh... this is the notable failing of deeply linked internal data structures: to figure out the size of any linked list of arbitrarily composed elements, the entire array needs to be "walked" every time the sizeof() or count() method is used.  But compared to the flexibility of associative arrays, the cost is mitigated by careful use.)

GoatGuy
nslater at gmail dot com
15-Mar-2005 10:12
In addition to the note made by "Francis dot a at gmx dot net" you should not normally be using a function such as sizeof() or count() in a control structure such as FOR because the same value is being calculated repeatedly for each iteration. This can slow things down immensely, regardless of whether you pass by value or reference.

It is generally much better to calculate the static values before the defining the looping control structure.

Example:

<?php

$intSize
= sizeof($arrData);

for(
$i = 0; $i < $intSize; $n++) {
  
// Do stuff
}

?>
Carlos
14-Mar-2005 03:09
in the example below, you would get the same result if you change the function to something like:

function test_ref(&$arr) {
   $time = time();
   $size = sizeof($arr);      // <--- this makes difference...
   for($n=0; $n<$size; $n++) {
       $x = 1;
   }

   echo "<br />The function using a reference took ".(time() - $time)." s";
}
Francis dot a at gmx dot net
09-Feb-2005 01:53
I don't know if this is a bug (I'm using PHP 5.01) but you should be careful when using  references on arrays.
I had a for-loop that was incredibly slow and it took me some time to find out that most of the time was wasted with the  function sizeof() at every loop, and even more time I spent  finding out that this problem it must be somehow related to the fact, that I used a reference of the array. Take a look at the following example:

function test_ref(&$arr) {
   $time = time();
   for($n=0; $n<sizeof($arr); $n++) {
       $x = 1;
   }
   echo "<br />The function using a reference took ".(time() - $time)." s";
}

function test_val($arr) {
   $time = time();
   for($n=0; $n<sizeof($arr); $n++) {
       $x = 1;
   }
   echo "<br />The funktion using a value took: ".(time() - $time)." s";
}

// fill array
for($n=0; $n<2000; $n++) {
   $ar[] = "test".$n;
}

test_ref($ar);
test_val($ar);
echo "<br />Done";

When I tested it, the first function was done after 9 seconds, while the second (although the array must be copied) was done in not even one.

The difference is inproportional smaller when the array size is reduced:
When using 1000 loops the first function was running for 1 second, when using 4000 it wasn't even done after 30 Seconds.
jw at jwscripts dot com
16-Oct-2004 08:18
Re-using variables which where references before, without unsetting them first, leads to unexpected behaviour.

The following code:

<?php

$numbers
= array();

for (
$i = 1; $i < 4; $i++) {
  
$numbers[] = null;
  
$num = count($numbers);
  
$index =& $numbers[$num ? $num - 1 : $num];
  
$index = $i;
}

foreach (
$numbers as $index) {
   print
"$index\n";
}

?>

Does not produce:
1
2
3

But instead:
1
2
2

Applying unset($index) before re-using the variable fixes this and the expected list will be produced:
1
2
3
hkmaly at bigfoot dot com
15-Sep-2004 11:11
It seems like PHP has problems with references, like that it can't work properly with circular references or free properly structure with more references. See http://bugs.php.net/?id=30053.

I have big problem with this and I hope someone from PHP add proper warning with explanation IN manual, if they can't fix it.
jlaing at gmail dot com
17-Jul-2004 11:28
While trying to do object references with the special $this variable I found that this will not work:
class foo {
  function bar() {
   ...
   $this =& $some_other_foo_obj;
  }
}

If you want to emulate this functionality you must iterate through the vars of the class and assign references like this:

$vars = get_class_vars('foo');
foreach (array_keys($vars) as $field) {
  $this->$field =& $some_other_foo_obj->$field;
}

Now if you modify values within $this they will be modified within $some_other_foo_obj and vice versa.

Hope that helps some people!

p.s.
developer at sirspot dot com's note about object references doesn't seem correct to me.

  $temp =& $object;
  $object =& $temp->getNext();

Does the same exact thing as:

  $object =& $object->getNext();

when you refernce $temp to $object all it does is make $temp an alias to the same memory as $object, so doing $temp->getNext(); and $object->getNext(); are calling the same function on the same object.  Try it out if you don't believe me.
thenewparadigm at hotmail dot com
07-May-2004 03:33
one very useful aspect for reference that i don't think i saw documented was the ability to skip a few steps with objects stored in objects.

for example:

assuming the object structure is correctly constructed (and mind you i haven't tried this in php, but it does work in most other high-end programming languages), instead of using this structure to get a variable/function

//start

$obj1 -> obj2 -> obj3 -> varX = 0;
$obj1 -> obj2 -> obj3 -> varY = 0;
$obj1 -> obj2 -> obj3 -> functionX();
$obj1 -> obj2 -> obj3 -> functionY();

//end

you can use this method:

//start

$tempObj = & $obj1 -> obj2 -> obj3;

$tempObj -> varX = 0;
$tempObj -> varY = 0;
$tempObj -> functionX();
$tempObj -> functionY();

//end

note, if you want to use a shortcut variable to modify the original object you must include the ampersand (&) to reference the variable, otherwise if you used this line of code

//start

$tempObj = $obj1 -> obj2 -> obj3;

//end

any changes you make to $tempObj will not change the original object and may compromise the object structure, not to mention that it takes up extra memory.  however, if you are just using the shortcut variable for read-only purposes, not using a reference wont cause any problems.

another alternative in programming languages is the 'with' structure as seen below

//start

with($obj1 -> obj2 -> obj3) {
   varX = 0;
   varY = 0;
   functionX();
   functionY();
}

//end

however, i don't expect this will work because as far as i've seen the 'with' structure is not supported in php.
nathan
06-Apr-2004 01:53
On the post that says php4 automagically makes references, this appears to *not* apply to objects:

http://www.php.net/manual/en/language.references.whatdo.php

"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."
iryoku at terra dot es
30-Mar-2004 01:22
You should have in mind that php4 keep assigned variables "automagically" referenced until they are overwritten. So the variable copy is not executed on assignment, but on modification. Say you have this:

$var1 = 5;
$var2 = $var1; // In this point these two variables share the same memory location
$var1 = 3; // Here $var1 and $var2 have they own memory locations with values 3 and 5 respectively

Don't use references in function parameters to speed up aplications, because this is automatically done. I think that this should be in the manual, because it can lead to confusion.

More about this here:
http://www.zend.com/zend/art/ref-count.php
developer at sirspot dot com
03-Feb-2004 01:30
Since references are more like hardlinks than pointers, it is not possible to change a reference to an object by using that same reference.  For example:

The following WILL NOT WORK as expected and may even crash the PHP interpreter:

$object =& $object->getNext();

However, by changing the previous statement to use a temporary reference, this WILL WORK:

$temp =& $object;
$object =& $temp->getNext();

<ExceptionsWhat References Do>
 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 18:35:34 2005 EDT