7

References:

  1. If I pass a variable to a function (e.g. $var), is that supposed to be a copy of a reference to the actual variable (such that setting it null doesn't affect other copies)?
  2. Or is it receiving a reference to what is a new copy of the actual variable (such that setting it to null destroys its copy only)?
  3. If the latter, does this copy objects and arrays in memory? That seems like a good way to waste memory and CPU time, if so.

I think can understand passing by reference (e.g. &$var) correctly by knowing how this works, first.

Scope:

  1. What's the deal with local scope? Am I right in observing that I can declare an array in one function and then use that array in other functions called within that function WITHOUT passing it to them as a parameter?
  2. Similarly, does declaring in array in a function called within a function allow it to be available in the caller?
  3. If not, does scoping work by a call stack or whatever like every bloody thing I've come to understand about programming tells me it should?

PHP is so much fun. :(

Hamster
  • 2,962
  • 7
  • 27
  • 38
  • Related (answers some of the questions asked here): [In php can someone explain cloning vs pointer reference](http://stackoverflow.com/questions/3611986/in-php-can-someone-explain-cloning-vs-pointer-reference/3612129#3612129) – ircmaxell Jan 20 '11 at 16:43
  • Please ask one question at a time. And for *each* question you should search to see if someone else has already answered your question. Most of these questions are duplicates. – zzzzBov Jan 20 '11 at 16:50

3 Answers3

2

If I pass a variable to a function (e.g. $var), is that supposed to be a copy of a reference to the actual variable (such that setting it null doesn't affect other copies)?

Depends on the function. And also how you call it. Look at this example: http://www.ideone.com/LueFc

Or is it receiving a reference to what is a new copy of the actual variable (such that setting it to null destroys its copy only)?

Again depends on the function

If the latter, does this copy objects and arrays in memory? That seems like a good way to waste memory and CPU time, if so.

Its going to save memory to use a reference, certainly. In php>4 it always uses reference for objects unless you specify otherwise.

What's the deal with local scope? Am I right in observing that I can declare an array in one function and then use that array in other functions called within that function WITHOUT passing it to them as a parameter?

No you can't.

Similarly, does declaring in array in a function called within a function allow it to be available in the caller?

No, it doesn't.

If not, does scoping work by a call stack or whatever like every bloody thing I've come to understand about programming tells me it should?

If you want to use a variable from outside the function, before using it, you'd write global $outsidevar

profitphp
  • 8,104
  • 2
  • 28
  • 21
  • What about using a variable defined in a caller function inside a callee function? The variable isn't in global scope then, is it? – Hamster Jan 20 '11 at 17:18
  • I'm not seeing output? Edit: That isn't what I meant exactly, though. I mean using 'global' to import the variable in that situation still works? – Hamster Jan 20 '11 at 17:30
  • http://www.ideone.com/UZbgB - Never mind, got it to work. Was missing – Hamster Jan 20 '11 at 17:39
  • Object references are not the same as variable references. Don't get them confused... – ircmaxell Jan 20 '11 at 17:42
  • Which reminds me: Arrays are like objects in that sense, correct? – Hamster Jan 20 '11 at 17:49
  • @hamster: No. In terms of reference, arrays are just like every other non-object. Objects are the only structure that have a separate internal reference system disjoint from variable references... – ircmaxell Jan 20 '11 at 17:52
  • @ircmaxell: Oooooh! So then I must use a reference to an array if I want to alter it in a callee function and expect to see its changes in the caller, right? – Hamster Jan 20 '11 at 17:56
  • @Hamster: Unless you return the object `return $array;` and assign it back over the original: `$array = foo($array);`, yes. If you declared `function foo(&$array) { ... }`, then you'd only need to call `foo($array)` and any changes made inside `foo` would be reflected in the starting array... – ircmaxell Jan 20 '11 at 17:58
  • @ircmaxell: And returning+copying back that array would be less efficient than passing by reference (for the purpose of applying changes), right? – Hamster Jan 20 '11 at 18:03
  • @Hamster: Don't worry about less-efficient unless you're dealing with huge arrays (10k+ elements). References can cause unexpected issues, so use them very sparingly... In fact, I would suggest not using them at all (I very rarely do, and in very explicit circumstances that don't come up often).. – ircmaxell Jan 20 '11 at 18:21
1

Concerning your first set of questions:

foo($a);
function foo($b) { echo $b; }

In this case, $a will not be copied to a new variable $b, only because it is passed by value.

This is because PHP uses the copy-on-write concept. PHP will not copy the contents of a variable, unless they are changed. Instead PHP will increment the refcount property of the existing "zval" of $a.

Well, the whole thing is not that trivial, but to answer your question: No, it does not copy the variable, unless you write to it in the function and no, you won't save CPU and Memory by using a reference. In most cases the reference won't change performance at all, but in the worst case it will actually degrade it (because if a not is_ref variant of the variable already exists and a reference is created the value of the variable must be copied to get a zval with is_ref and one without). Optimizing code by using references is no good.

NikiC
  • 100,734
  • 37
  • 191
  • 225
  • It may not be a good optimization tip for squeezing out performance, but it certainly does save memory to use a reference. Especially with objects, since they can get large. Nevermind.. just was researching it, i thought they were like pointers.. they act like it. but they are not. – profitphp Jan 20 '11 at 17:14
1

if argument to a function is defined as so "function my_function($variable) {}" then you are getting a copy of the variable and any alterations made to the variable inside your function will not be available to the function caller. you can pass a variable by reference by prepending an ampersand to the argument when defining your function and thus any alterations made to the variable will persist to the function caller, ie "function my_function(&$variable) {}"

function myfunction($var) {
    $var = 'World';
}
$var = 'Hello';
myfunction($var);
echo $var; // 'Hello';

Passing a variable by reference

function myfunction(&$var) {
    $var = 'World';
}
$var = 'Hello';
myfunction($var);
echo $var; // 'World'
KrisA
  • 51
  • 7