tags:

views:

390

answers:

5
+1  Q: 

Php By Reference

Hello,

Can someone please explain what the "&" does in the following:

class TEST {

}

$abc =& new TEST();

I know it is by reference. But can someone illustrate why and when I would need such a thing? Or point me to a url where this is explained well. I am unable to grasp the concept.

Thank you very much.

+1  A: 

Firstly, you don't really need to use it if you are using PHP 5, in PHP 5 all objects are passed by reference by default.

Secondly, when you assign an object to a variable name, either by creation, passing in a parameter, or setting a variable value, you are either doing so by reference or value.

Passing by reference means you pass the actual memory reference for the object, so say you passed an object as a parameter to a function, any changes that function makes to that variable will be reflected in the parent method as well, you are actually changing the state of that object in memory.

The alternative, to pass by value means you pass a copy of that object, not the memory reference, so any changes you make, will not be reflected in the original.

Sam Cogan
Alec Smart
Well, your telling PHP that when the new object is created, you want PHP to assign hte memory address of this new object to $abc variable. This is now the default behaviour of PHP.
Sam Cogan
@Sam_Cogan: Not really: check http://www.php.net/manual/en/language.oop5.references.php
Christoph
I stand corrected!
Sam Cogan
+1  A: 

The PHP Manual does a pretty decent job of explaining references.

I should note, that they are NOT the same thing as a pointer or a reference in many other languages, although there are similarities. And as for objects being "passed by reference" by default - that's not exactly true either.

I would recommend reading the manual section first (and probably then re-reading a couple of times until you get it), and then come back here if you still have more questions.

Vilx-
A: 

A simpler way to look at it may be like this:

$a = 'foo';
$b = 'bar';
$a =& $b;
$b = 'foobar';
echo $a . ' ' . $b;

will output

foobar foobar
Unkwntech
WTF? Are you sure this works? O_oBesides - this is PHP4 code.
Vilx-
No but I'm running PHP5 so I can't check, I removed it and went with the example I know workds.
Unkwntech
References works the same in PHP4 and PHP5.
troelskn
+8  A: 

As I understand it, you're not asking about PHP references in general, but about the $foo =& new Bar(); construction idiom.

This is only seen in PHP4 as the usual $foo = new Bar() stores a copy of the object. This generally goes unnoticed unless the class stored a reference to $this in the constructor. When calling a method on the returned object later on, there would be two distinct copies of the object in existence when the intention was probably to have just one.

Consider this code where the constructor stores a reference to $this in a global var

class Bar {
    function Bar(){
       $GLOBALS['copy']=&$this;
        $this->str="hello";
    }

}

//store copy of constructed object
$x=new Bar;
$x->str="goodbye";

echo $copy->str."\n"; //hello
echo $x->str."\n"; //goodbye

//store reference to constructed object
$x=&new Bar;
$x->str="au revoir";

echo $copy->str."\n"; //au revoir
echo $x->str."\n"; //au revoir

In the first example, $x and $copy refer to different instances of Foo, but in the second they are the same.

Paul Dixon
Alec Smart
That's correct. There's a marginal performance improvement, but if you want to write php4 code in a php5 style, I wouldn't bother getting into the habit.
Paul Dixon
A: 

It might be helpful to think of it like this: In PHP, all variables are really some sort of pointer: The entries in the symbol table - the thing which maps variable names to values - contain a zval * in the C implementation of the Zend Engine.

During assignment - this includes setting function arguments - magic will happen:

If you do $a = $b, a copy of the value pointed to by the symbol table entry of $b will be created and a pointer to this new value will be placed in the symbol table entry for $a. Now, $a and $b will point to different values. PHP uses this as its default calling convention.

If you do $a =& $b, the symbol table entry for $a will be set to the pointer contained in the symbol table entry for $b. This means $a and $b now point to the same value - they are aliases of each other with equal rights until they are rebound by the programmer. Also note that $a is not really a reference to $b - they are both pointers to the same object.

That's why calling them 'aliases' might be a good idea to emphasize the differences to C++' reference implementation:

In C++, a variable containing a value and a reference created from this variable are not equal - that's the reason why there are things like dangling references.

To be clear: There is no thing like a reference type in PHP, as all variables are already internally implemented as pointers and therefore every one of them can act as a reference.

PHP5 objects are still consistent with this description - they are not passed by reference, but a pointer to the object (the manual calls it an 'object identifier' - it might not be implemented as an actual C pointer - I did not check this) is passed by value (meaning copied on assignment as described above).

Check the manual for details on the relation between PHP5 objects and references.

Christoph
Actually, that's a pretty bad and misleading explanation. References in PHP are not pointers. A references means that the value of the reference will always be the value of the referred variable - Even if this changes. Rather confusing.
troelskn
Actually, afaik the symbol table in PHP (the thing which maps variable names to values) contains pointers to zval (zval is the type for PHP values used in zend); so EVERY variable is actually a pointer! I might clarify this a bit...
Christoph
@troelskn: The last edits should make clear what is actually happening 'under the hood'
Christoph