ONLamp.com    
 Published on ONLamp.com (http://www.onlamp.com/)
 See this if you're having trouble printing code examples


PHP Foundations PHP References

by John Coggeshall
08/16/2002

Welcome back. In my last article, I wrapped up my discussion of using objects in PHP. This week I'll be changing gears a little bit and discussing one of the more elusive aspects of PHP -- references. For those of you with a C programming background (although they are fundamentally different), references serve the same purpose as a C-style pointer. For those of you without programming experience in C, don't worry! I'll be covering everything you'll need to know today.

Basic References Explained

Regardless of your background, the concept of a reference in PHP can be a bit difficult to grasp until properly explained. As I mentioned earlier, PHP references serve the same purpose as a memory pointer in a C-style language. For those of you who aren't familiar with C or similar languages, I'll explain further.

As its name implies, a reference in PHP is a variable that "references" the contents of another variable. For instance, consider the following small piece of code:

<?php
    $foo = 5;
    $bar = $foo;
    for(int $i = 0; $i < 5; $i++) {
        echo "The value of foo is: $foo, and the value of bar is: $bar<BR>";
        $foo++;
        $bar--;
    }
?>

When the above code executes, what will be the result? You should have no problem seeing that as the loop cycles through, the result will be five lines of text, output to the client in the following fashion:

The value of foo is: 5, and the value of bar is 5
The value of foo is: 6, and the value of bar is 4
....
The value of foo is: 10, and the value of bar is: 0

The point is that the variables $foo and $bar are independent of each other, and each can be modified without any other variables being affected. PHP references allow the developer to tie two separate variables together, allowing you to modify both at once. Let's consider the following, slightly modified version of the above code:

<?php
    $foo = 5;
    $bar =& $foo;
    for(int $i = 0; $i < 5; $i++) {
        echo "The value of foo is: $foo, and the value of bar is: $bar<BR>";
        $foo++;
        $bar--;
    }
?>

Notice that the second line in the above code has changed. Instead of simply assigning the value of $foo to the variable $bar, we now have used the =& operator to set the variable $bar as a reference to the variable $foo. What's the difference? Let's see when the code is again executed:

The value of foo is: 5, and the value of bar is: 5
The value of foo is: 5, and the value of bar is: 5
....
The value of foo is: 5, and the value of bar is: 5

As you can see, neither variable seemed to move from its original value! Although you might at first consider this a bug, let's look at the code line-by-line. First we start by assigning the integer value 5 to the variable $foo. Next, we create a reference to the variable $foo and call it $bar. As we enter the for loop, we print the contents of both variables and as expected, both are equal to five. Then we increment the value of $foo, decrement the value of $bar, and repeat. But why did the values of $foo and $bar remain constant?

In the first example, we took a value of 5 and assigned it to the variable $foo. Then, we created a second variable, $bar, and assigned it the same value as $foo. However, notice that a second variable $bar was created, and thereby is completely independent of the first. In contrast, the second example created a reference to $foo and called it $bar. When this is done, a second variable is not created, but rather a single variable is given another variable name, as shown below:


Figure 1: $foo and $bar as independent variables


Figure 2: $bar as a reference to the variable $foo

As you can see by the above illustrations, PHP references allow you to work with the same physical data using different names. Looking back at the second example, you can now see that when the variable $foo was incremented, it indeed was assigned a value of 6. However, because $bar is a reference to the variable $foo, when it was decremented in the following line, $foo was again set to the value of 5. The result, of course, is that the script appeared to never change the value of the variables at all!

Programming PHP

Related Reading

Programming PHP
By Rasmus Lerdorf, Kevin Tatroe

References and Arrays

Just like standard variables, references can also be used in conjunction with arrays. A PHP reference can occur for an entire array, or for a specific index. For instance, let's take a look at the script below that creates three different references to variables contained with an array:

<?php
    $myarray = array(0=>'variable1', 1=>'variable2', 2=>'variable3');
    $ref1 = &myarray;       // Reference the entire Array
    $ref2 = &myarray[0];    // Reference to the first index
    $ref3 = &myarray[1];    // Reference to the second index
?>

Passing By Reference

Beyond the use of references when working with standard variables, references can also be used in conjunction with function parameters. This ability proves especially useful when it would be desirable to return more than one result from a given function. For instance, let us assume that we would like to create a function called split_string() to cut a string in half. This function takes two parameters, a string and an integer, and returns two strings representing the two halves. Unfortunately, the nature of a function does not allow us to return two different variables, so another solution must be determined. One possibility would be to store the two halves of the result into an array and return an array of strings. For another solution, take a look at the following code:

<?php
    function split_string($input, $cut_point, &$first, &$second) {
        if(strlen($input) < $cut_point) return false;
        $first = substr($input, 0, $cut_point);
        $second = substr(input, $cut_point);
        return true;
    }
?>

In this solution, the split_string() function created takes not two, but four parameters. The first two parameters have already been described, while the second two parameters are actually references to the variables where the result will be stored. Also note that this function's return value is a boolean indicating the success of the function. This function is called as follows:

<?php
    $input_text = "abcdefghijklmnopqrstuvwxyz";
    if(split_string($input_text, 30, &$first_half, &$second_half) != true) {
        echo "Could not split input, cut-point is entire string!";
        echo "<BR>";
    }

    if(split_string($input_text, 10, &$first_half, &$second_half) == true) {
        echo "First segment of input: $first_half<BR>";
        echo "Second segment of input: $second_half<BR>";
    }
?>

This would produce an output as follows:

Could not split input, cut-point is entire string!
First segment of input: abcdefghij
Second segment of input: klmnopqrstuvwxyz

As you can see, because the function utilized reference-passing, we were able to successfully return two separate parameters from the function with ease, and left the return value to be used for error checking. Although not always the best course of action, the ability to pass parameters by reference provides a great deal of flexibility to the developer (especially when used in the design of advanced algorithms).

More References Later

That's all the time this week for our discussion of references! In my next article I will continue my discussion of references by explaining the more advanced techniques of using references, including how references are implemented in objects and how to return a reference as the direct result of a function (using a return statement).

John Coggeshall is a a PHP consultant and author who started losing sleep over PHP around five years ago.


Read more PHP Foundations columns.

Return to the PHP DevCenter.


Copyright © 2009 O'Reilly Media, Inc.