PHP Variables: Passing by Value or Reference

May 24, 2009

An issue to consider when programming is how variables are passed from one context to another. For example, the following code calls a function, referencing a variable in doing so:

$it = 'Larry';
some_function($it);

Will the function receive just the value of that variable (Larry) or will it receive the variable itself? The answer depends upon how the function is defined. In this post, I’ll explain this concept further, in not too-technical terms.Starting with the inner-workings of a programming language, you have to understand that there are several aspects to a variable. In PHP, when a variable is assigned a value, you have three things:

  • The variable’s name (like it in the above example)
  • The variable’s value (Larry)
  • Memory allotted on the computer, where that value will be stored.

(There’s a bit more going on but…)

Because PHP takes care of all the dirty work (and is generally an easy language to use), you don’t need to concern yourself with this last thing. All you have to do is refer to a variable (after it’s been assigned a value) to retrieve that value. By default, when you use that variable in a function call as in the above, you’re passing the value of the variable to the function, not the variable itself. In other words, in that above list of three things, only the middle thing—the value—is received by the function. Take this example:

$it = 'Larry';
function say_hello ($thing) {
    echo "Hello, $thing";
}
say_hello($it);

That code is functionally equivalent to

say_hello('Larry');

An important consideration when it comes to passing variables by value is that if the function changes the value of $thing, the $it variable outside of the function is unaffected:

$it = 'Larry';
function say_hello ($thing) {
    echo "Hello, $thing";
    $thing = 'World';
}
say_hello($it);
say_hello($it);

Those two function calls will print the same Hello, Larry message twice.

So that’s passing by value in a nutshell, which again is the default behavior (most of the time; more on exceptions later). PHP also allows you to pass variables by reference instead of by value. You can do so by changing the function definition, prepending the variable(s) to be received by reference with an ampersand:

$it = 'Larry';
function say_hello (&$thing) {
   echo "Hello, $thing";
   $thing = 'World';
}
say_hello($it);
say_hello($it);

In that example, the actual variable is being passed to the function (in layman’s terms), not its value. As the PHP manual nicely describes it, both variables (i.e., $thing and $it) will be pointing to the same content, which is to say, pointing to the same place where that value is stored (similar to, but not exactly the same as pointers in C/C++).

Passing by reference also means that when the second variable’s value is changed, it’s changed for the original variable, too. In the most recent example, Hello, Larry will be printed once, followed by Hello, World, and $it outside of the function now has a value of World.

So that’s the fundamentals of passing by value vs. passing by reference. I don’t want to extend this too far, so as not to end up confusing you, but I’ll mention a couple of other random bits:

  • Older versions of PHP allowed you to pass a variable by reference in the function call: say_hello(&$it), but this has been phased out.
  • Some argue that passing by reference is faster for more complicated variables (like arrays and objects), but it’s best not to use passing by reference just to improve performance. PHP does lots of performance optimization on its own.
  • You can pass variables by reference not just in function calls, as in my examples, but also when using the assignment operator: $a =& $b. Now a change to the value of $a or $b will affect the value of the other.
  • As of PHP 5, objects are passed by reference by default when using the assignment operator. In PHP 4, they were passed by value.
  • For a great description of the inner workings involved, see Derick Rethans article.

Finally, for an interesting real-world look at how this affects PHP programming, take an example where you’re using prepared statements with a database, like MySQL:

$stmt = mysqli_prepare($dbc, 'INSERT INTO tablename (something) VALUES (?)');
mysqli_stmt_bind_param($stmt, 's', $somevar);
$somevar = 'blah';
mysqli_stmt_execute($stmt);

The mysqli_stmt_bind_param() function receives the variables by reference, which is why the variable can (and often is) assigned a value after it’s named in the function call, but before the mysqli_stmt_execute() function call. Once the execute function is called, PHP will grab the value of the variable through the reference, to use in the query.