References

Posted by lec** on Saturday, October 06 2007 @ 22:00:20 GMT        
If you're not familiar with the concept of references, it's safe to assume you do not understand precisely how variables "work" in PHP. When you create a variable, whatever data you assigned to it gets stored in the server's memory, and it remains there to be subsequently accessed by your code later. Take the simple example $var = 3; - that instructs the PHP interpreter to store the number three in memory, which you will from that point onwards be able to use in your script. Wherever you use $var, you are really using the number 3. Now let's create another variable, $other = $var;. What happens here? Well, PHP discovers that $var contains the number 3, and stores that in memory too, so that you can use echo $other; to print 3.

Resulting from this, $var and $other have nothing in common except that they contain the number 3. They are two distinct variables that point to different memory locations: though echo $var; and echo $other; both print out "3", the number three in each case is coming from a different source, a different memory location. In short, you've got two "3"s in memory that these two variables identify. So what? Well, this of course means that you can change them independently of one another. Changing $var to 4 won't affect $other, which will remain 3. Let's illustrate this, though you know this well already:

<?php 
$var = 3;
$other = $var; // make $other also equal to 3

echo $var; // prints 3
echo $other; // prints 3

$other = 17; // change $other to something else

echo $var; // prints 3
echo $other; // prints 17
?>
]]>

Now that's all very simple, basic PHP which you of course have no problems understanding. Now let's introduce the concept of references. References are a way of getting two different identifiers ($var and $other, for example) identify the same memory locaton. They are not like pointers in C, they're just a way to have two differently-named variables identify the same thing. This is often highly useful, as you'll see later. The way to do this is by using the referencing operator (& - the ampersand) to get this effect. Pay close attention...

<?php 
$var = 3;
$other =& $var;
// ^--- this does not create a new variable, it rather makes using $other
// the same as if you were using $var. $other is now an alias, or reference to $var.

echo $var; // prints 3
echo $other; // prints 3

$other = 17; // change $other to something else

echo $var; // prints 17
echo $other; // prints 17
?>
]]>

A common first reaction when seeing a referencing example is confusion, so I'll explain what just happened line by line. $var = 3; created a new variable and stored 3 in it. $other =& $var; made $other a reference to $var - $other now points to whatever is contained within $var, it's not a copy of $var! Using $other++; is now the same as using $var++; - $other referenced $var, therefore they have now become interchangeable.

Echoing $var and $other printed 3 like in the above example, only in this case the number "3" comes from the same resource in memory, not from two different ones. echo $var; echo $other; is the same as doing echo $var; echo $var;. And finally, just to prove that they are now one and the same, $other = 17; updates the data at the memory location identified by $other - which is the same one as the location identified by $var - and thus in the last set of echo()s, they both print out 17. It's very important to fully understand this before you can get to any practical uses, so please make sure you completely understand everything so far.


Part 2: Getting Practical
Now you understand how references work, it's time to see where you can use them in your code. Often, they can help you get things done quicker and simpler, but I have found irreplacable roles for them too.

Pass by reference to functions
Whenever you call a function, like function($parameter);, the $parameter gets passed as a copy into the function. This means that nothing actually happens to $parameter, but to a copy of it. Sometimes, you may want to do the actual processing WITH the parameter passed into the function, rather than on a copy (that you have to return later). This examples demonstrates such a use:

<?php 
// Example #1 - no referencing
function multiply_by_ten($number)
{
return $number * 10;
}

$my_number = 35;
$my_number = multiply_by_ten($my_number);
echo $my_number; // prints out 350

// Example #2 - pass-by-reference
function multiply_by_ten(&$number)
{
$number = $number * 10;
}

$my_number = 35;
multiply_by_ten($my_number);

echo $my_number; // prints out 350
?>
]]>

In essence, running the first version of multiply_by_ten() on a number would return the number multiplied by 10. The second version featuring pass-by-reference doesn't return anything - it preforms the operation on the actual parameter ($my_number) and therefore $my_number gets changed within the function itself. That's the power of referencing. A good use of this power would be to overcome the fact that a function can only return one thing at one time. With references, a function accepting several referenced parameters could preform processing directly on them, thereby effectively carrying out various types of processing on many variables simultaneously. Oh, and I almost forgot to mention - you can reference all of PHP's variable types, not just integers - floats, strings, arrays and objects, which means you can do a whole lot of cool stuff with them.

Looping through arrays
This is more of a shortcut use of references, to help you code array loops quicker and easier. Usually when you loop through an array in some way with foreach, copies of the array are created for use within the construct - so editing an array key by key in this way may not be the simplest method. Again, here are two ways of looping to demonstrate references:

<?php 
// In this example, our goal is to eliminate all non-fruit entities within this array

$fruit = array(
1 => 'apple',
2 => 'carrot',
3 => 'pear',
4 => 'orange',
5 => 'pepper',
6 => 'pea',
7 => 'watermelon',
8 => 'lemon',
);


// first example of the loop - no references
foreach ($fruit as $fruitid => $suspected_vegetable)
{
if ($suspected_vegetable == 'carrot' || $suspected_vegetable == 'pepper'
|| $suspected_vegetable == 'pea')
{
// not referenced - you have to manually update the array
$fruit["$fruitid"] = '---';
}
}

// first example of the loop - with references
foreach ($fruit as $fruitid => &$suspected_vegetable)
{
if ($suspected_vegetable == 'carrot' || $suspected_vegetable == 'pepper'
|| $suspected_vegetable == 'pea')
{
$suspected_vegetable = '---';
}
}
?>
'apple', 2 => 'carrot', 3 => 'pear', 4 => 'orange', 5 => 'pepper', 6 => 'pea', 7 => 'watermelon', 8 => 'lemon', ); // first example of the loop - no references foreach ($fruit as $fruitid => $suspected_vegetable) { if ($suspected_vegetable == 'carrot' || $suspected_vegetable == 'pepper' || $suspected_vegetable == 'pea') { // not referenced - you have to manually update the array $fruit["$fruitid"] = '---'; } } // first example of the loop - with references foreach ($fruit as $fruitid => &$suspected_vegetable) { if ($suspected_vegetable == 'carrot' || $suspected_vegetable == 'pepper' || $suspected_vegetable == 'pea') { $suspected_vegetable = '---'; } } ?> ]]>

Using references in the above example allowed me to directly modify the values in the array, without having to use the array key to do the same thing. You could say there's not much of a difference, but I think the second piece of code is very easy to understand on the first read, without the need to look at the array again and confirm that the replacement is being done correctly.

There are more uses of references of course. For example, one piece of code I wrote involved passing objects to other objects, to other objects, and so on. Some of these objects kept count of stuff, like the time and number of queries being used, and they needed to be passed temporarily through the objects to be used by them. If I hadn't used references to pass them directly from one object to another, that data would have been lost as a result of them being copied between passes. Now you know the basics of references, you can find uses for them in your own applications to simplify your code and make things easier for yourself. Whew!
Conventional Login

Don't have an account? You may want to create one.

OpenID Login
OpenID login and registration is usable, but not finished.
What is OpenID?
Search

(advanced search)
Site Stats
  Total members: 108
  Latest member: adamthephantump
  Members currently online: 0
  Most online: 5 - Aug 28, 2009 (21:49)
  Front page hits: 87981
Developer info
  Site version: 3.5 Alpha
  12 queries - 4 templates
Under the Spotlight
Collide Site
Collide make fabulously dreamy electronic-industrial music, they're one of my favourite bands! Give them a chance to take control of your life - myspace | youtube - "Euphoria".

Collide Site - Hits: 4590

5/5 (2) | Rate this site?