52

In C++ if you pass a large array to a function, you need to pass it by reference, so that it is not copied to the new function wasting memory. If you don't want it modified you pass it by const reference.

Can anyone verify that passing by reference will save me memory in PHP as well. I know PHP does not use addresses for references like C++ that is why I'm slightly uncertain. That is the question.

  • 2
    Just a C++ related note: Arrays passed to functions are actually pointers, so passing a reference to them is unnecessary and doesn't actually do what you think it does. Totally agree on the const though! – Aaron Jul 13 '12 at 19:33

3 Answers3

74

The following does not apply to objects, as it has been already stated here. Passing arrays and scalar values by reference will only save you memory if you plan on modifying the passed value, because PHP uses a copy-on-change (aka copy-on-write) policy. For example:

# $array will not be copied, because it is not modified.
function foo($array) {
    echo $array[0];
}

# $array will be copied, because it is modified.
function bar($array) {
    $array[0] += 1;
    echo $array[0] + $array[1];
}

# This is how bar shoudl've been implemented in the first place.
function baz($array) {
    $temp = $array[0] + 1;
    echo $temp + $array[1];
}


# This would also work (passing the array by reference), but has a serious 
#side-effect which you may not want, but $array is not copied here.
function foobar(&$array) {
    $array[0] += 1;
    echo $array[0] + $array[1];
}

To summarize:

  • If you are working on a very large array and plan on modifying it inside a function, you actually should use a reference to prevent it from getting copied, which can seriously decrease performance or even exhaust your memory limit.

  • If it is avoidable though (that is small arrays or scalar values), I'd always use functional-style approach with no side-effects, because as soon as you pass something by reference, you can never be sure what passed variable may hold after the function call, which sometimes can lead to nasty and hard-to-find bugs.

  • IMHO scalar values should never be passed by reference, because the performance impact can not be that big as to justify the loss of transparency in your code.

fresskoma
  • 25,481
  • 10
  • 85
  • 128
  • 1
    Thanks and +1 for the explanation. Since I had difficulties finding infos on copy-on-change: look (google) for "copy on write" and you'll get to http://php.net/manual/en/internals2.variables.intro.php – dennis Jun 28 '13 at 14:54
13

The short answer is use references when you need the functionality that they provide. Don't think of them in terms of memory usage or speed. Pass by reference is always going to be slower if the variable is read only.

Everything is passed by value, including objects. However, it's the handle of the object that is passed, so people often mistakenly call it by-reference because it looks like that.

Then what functionality does it provide? It gives you the ability to modify the variable in the calling scope:

class Bar {}
$bar = new Bar();

function by_val($o) { $o = null; }
function by_ref(&$o) { $o = null; }

by_val($bar); // $bar is still non null
by_ref($bar); // $bar is now null

So if you need such functionality (most often you do not), then use a reference. Otherwise, just pass by value.

Functions that look like this:

$foo = modify_me($foo);

sometimes are good candidates for pass-by-reference, but it should be absolutely clear that the function modifies the passed in variable. (And if such a function is useful, often it's because it really ought to just be part of some class modifying its own private data.)

Matthew
  • 47,584
  • 11
  • 86
  • 98
10

In PHP :

  • objects are passed by reference1 -- always
  • arrays and scalars are passed by value by default ; and can be passed by reference, using an & in the function's declaration.


For the performance part of your question, PHP doesn't deal with that the same way as C/C++ ; you should read the following article : Do not use PHP references


1. Or that's what we usually say -- even if it's not "completely true" -- see Objects and references

Pascal MARTIN
  • 395,085
  • 80
  • 655
  • 663
  • I'm slightly confused.. does this mean I'd be able to create a singleton class and pass a reference to each visitor of a site, instead of querying the database for each of them ? (all the visitors are requesting the same data) – sdadffdfd Mar 29 '11 at 21:27
  • 5
    In PHP, you will not have a Singleton "per server" -- but a singleton "per execution of a script". Each user will have its distinct, separate, execution of the script -- which means each one will have its own memory space ; your singleton will be a singleton for one execution of the script ; and each execution of the script will have its own instance of your singleton. – Pascal MARTIN Mar 29 '11 at 21:29
  • that's sad.. would be great to have such a feature in php. Thanks. – sdadffdfd Mar 29 '11 at 21:31
  • Unless you serialize the data to a database or disk. – Adriano Varoli Piazza Mar 29 '11 at 21:34
  • there are caching modules you can use to cache data in the way that you describe. – dqhendricks Mar 29 '11 at 21:41
  • The database itself ? Or the connection ? If you plan on serializing the connection, remember that resources *(as returned by mysql_connect, for example)* cannot be serialized, and 'you'll have to re-connect when trying to de-serialize it. – Pascal MARTIN Mar 29 '11 at 21:41
  • @Pascal MARTIN - the data retrieved from the db. – dqhendricks Mar 29 '11 at 21:42
  • Then, some caching mecanism, such as APC or memcached, would do just fine ;-) – Pascal MARTIN Mar 29 '11 at 21:57
  • @sdadffdfd that would be a potentially dangerous feature. Imagine your singleton `user` object shared by everyone, everyone would be logged in to the same user :P. We have disk and memory caching for such things, imo better to keep them seprate – James Jul 08 '22 at 14:37