tags:

views:

125

answers:

3

What does the & before the function name signify?

Does that mean that the $result is returned by reference rather than by value? If yes then is it correct? As I remember you cannot return a reference to a local variable as it vanishes once the function exits.

function &query($sql) {
 // ...
 $result = mysql_query($sql);
 return $result;
}

Also where does such a syntax get used in practice ?

+3  A: 

Does that mean that the $result is returned by reference rather than by value?

Yes.

Also where does such a syntax get used in practice ?

This is more prevalent in PHP 4 scripts where objects were passed around by value by default.

BoltClock
-1 for stating $result would only exist within the function and would therefore be useless.
nikic
@nikic: I rolled my answer back.
BoltClock
Okay. So now I give -1 for saying that objects are not passed by value in PHP 5 anymore...
nikic
@nikic: do you have any support for your claim that objects in php5 **are** passed by value?
Dennis Haarbrink
Sure. Try this: `$a = new stdClass; test($b) { $b = 'test'; }; echo test($a);`. This should output `test`, not the `stdClass`. Further reading: http://saragolemon.blogspot.com/2007/01/youre-being-lied-to.html. (Okay I admit, this is a little bit pedantic, but why not be precise?)
nikic
@nikic: I don't think that proves that objects are passed by value. If you set a local variable to a new value, it's not the same object. You'd have to write a function that modifies an object of some mutable type and show that the value passed in was not changed externally to prove that the parameter was passed by value (copied).
Dan Tao
@nikic: your example is a bit convoluted since you are intermingling object and string datatypes. a correct example would be: `$a = new stdClass; $a->prop='foo'; function test($b){ $b->prop = 'bar'; } test($a); echo $a->prop;` As you can see, the object is passed by-ref :)
Dennis Haarbrink
I think I have written my comment badly, I meant to say "If objects were passed by reference, this would output `test`, not the `stdClass`". @Dennis: Why do you think this is convoluted? If I did the same with pass-by-reference, i.e. used `test( };` instead, the script really **would** output `test` as expected with references. But maybe my terminology isn't correct, too, because actually the object **does** behave reference-*like*, because it isn't passed around at all, but only a pointer to it is passed - but this pointer is passed by-value.
nikic
@nikic: allright, the answer lies somewhere in the middle. When dealing with objects, and objects only, (which is fully expected) it exhibits full by-ref behaviour. Apparantly there are some weird corner cases where there's some WTF involved.
Dennis Haarbrink
@Dennis: Yeah, normally objects can be regarded as references. But I think it is worth knowing what they aren't and it's worth knowing that PHP uses copy-on-write, too. (That's the second thing Golemon talks about in that blog entry.)
nikic
And for those who want to know how copy-on-write in PHP works in scientific detail, here is a PDF for you: http://www.trl.ibm.com/people/mich/pub/200901_popl2009phpsem.pdf
Gordon
What PHP calls "objects" are always passed by value unless otherwise noted. The difference between PHP4 and PHP5 is that in PHP5 you pass around references to the objects.
Artefacto
+1  A: 

To answer the second part of your question, here a place there I had to use it: Magic getters!

class FooBar {
    private $properties = array();

    public function &__get($name) {
        return $this->properties[$name];
    }

     public function __set($name, $value) {
        $this->properties[$name] = $value;
    }
}

If I hadn't used & there, this wouldn't be possible:

$foobar = new FooBar;
$foobar->subArray = array();
$foobar->subArray['FooBar'] = 'Hallo World!';

Instead PHP would thrown an error saying something like 'cannot indirectly modify overloaded property'.

Okay, this is probably only a hack to get round some maldesign in PHP, but it's still useful.

But honestly, I can't think right now of another example. But I bet there are some rare use cases...

nikic
A: 

Does that mean that the $result is returned by reference rather than by value?

No. The difference is that it can be returned by reference. For instance:

<?php
function &a(&$c) {
    return $c;
}
$c = 1;
$d = a($c);
$d++;
echo $c; //echoes 1, not 2!

To return by reference you'd have to do:

<?php
function &a(&$c) {
    return $c;
}
$c = 1;
$d = &a($c);
$d++;
echo $c; //echoes 2

Also where does such a syntax get used in practice ?

In practice, you use whenever you want the caller of your function to manipulate data that is owned by the callee without telling him. This is rarely used because it's a violation of encapsulation – you could set the returned reference to any value you want; the callee won't be able to validate it.

nikic gives a great example of when this is used in practice.

Artefacto