3

I can change $var in my function in one of two ways: either pass it by reference or using the global keyword.

$var1 = 10;

function test1() {
    global $var1;
    $var1++;
}

function test2(&$var) {
    $var++;
}

Both approaches have the same result, but is there any difference between them? Which one is preferred and which one is faster?

Jon
  • 428,835
  • 81
  • 738
  • 806
Moein Hosseini
  • 4,309
  • 15
  • 68
  • 106
  • 1
    simply put: one is [plague](http://stackoverflow.com/questions/5166087/global-in-functions/5166527#5166527), the other is [cholera](http://schlueters.de/blog/archives/125-Do-not-use-PHP-references.html). – Gordon Sep 13 '11 at 11:01

3 Answers3

5

1. None of them is preferred.

Unless you have a special reason to do otherwise, the preferred would be

$var1 = 10;
$var1 = test3($var1);
function test3($var)
{
    return $var + 1;
}

Introducing coupling between different parts of your program (if using a global) is something you should always reasonably try to avoid.

In addition, if there is no concrete reason to make your function accept its argument by reference you should also avoid doing that. Only a very miniscule fraction of all functions behave this way, so if nothing else you are risking confusion among the developers who use this code for no real benefit.

2. You do not need to think about which one is faster.

Unless you have profiled your application under real world scenarios and have found that this function is a bottleneck (which of course it will never be in this simple form), then optimizing for performance at the expense of writing clear and maintainable code is not only pointless, but also detrimental.

As a bonus, I should mention that using a reference might actually make the function slower.

Community
  • 1
  • 1
Jon
  • 428,835
  • 81
  • 738
  • 806
  • I don't think this would be the preferred method, if you use a big array for example you can't just make multiple copy of it. – Jaffa Sep 13 '11 at 10:55
  • @Geoffroy: On what grounds do you say that? Have you actually made any tests? Do you know that passing arrays by reference in PHP [was](http://php.net/manual/en/language.references.php#60979) and [still is](http://stackoverflow.com/questions/178328/in-php-5-0-is-passing-by-reference-faster) notoriously slow? – Jon Sep 13 '11 at 11:01
  • perhaps, but it is still better than copying arrays that may contains objects and even singleton. And if your array is 500 Mo weight, then would you copy it? It is even slower than referencing it. – Jaffa Sep 13 '11 at 11:06
  • @Geoffroy: If your array is 500Mb you should not have read all of it in memory in the first place. Let's not express opinions based on ifs and buts -- the OP asks about what is better *in general*. Consider also that you may be wrong: PHP uses copy on write for referenced arrays, so you would not actually gain any speed at all if you modify the array. – Jon Sep 13 '11 at 11:09
  • I admit your responses make senses, and I don't know that much about PHP. But following your saying, why does PHP 5.3 uses automatic reference for object? (It does, if I don't mistake) – Jaffa Sep 13 '11 at 11:12
  • @Geoffroy: It would be better to have this discussion [in chat](http://chat.stackoverflow.com/rooms/3402/chat-with-geoffroy). – Jon Sep 13 '11 at 11:24
1

Since global variables pollute the namespace (i.e. can be used inadvertently and/or by another function with the same idea), references are preferable.

However, in many cases (where the data structures are more complex), you should be using objects instead, like this:

class Counter {
  private $val = 10;
  public function increment() {
    $this->val++;
  }
}

The speed of any of these solutions does not matter and will be dwarfed by any actual computation.

phihag
  • 278,196
  • 72
  • 453
  • 469
1

Preferred way is avoiding globals. The reason is that if you put a variable in global scope, you lose control over it - since projects grow, you might forget what the name of your global variable is and you can overwrite it accidentally somewhere causing an incredible headache for yourself.

From performance point of view - reference is faster and it's also much safer to use because you define in method's signature whether a reference is being used or not, making the actual function call easy as you don't have to pass the variable by reference explicitly.

N.B.
  • 13,688
  • 3
  • 45
  • 55