Referencing (OOP)

Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.

Moderator: General Moderators

Post Reply
Nay
Forum Regular
Posts: 951
Joined: Fri Jun 20, 2003 11:03 am
Location: Brisbane, Australia

Referencing (OOP)

Post by Nay »

Ah, long time no post. A while ago I asked about the little '&' that exists in some OOP classes. Wierdan pointed me out the the PHP manual and told me it's called referencing (If my memory serves me correctly).

Anyhow, I have read over it quite a few times and still do not get it. I was wondering if someone could point out to me 1) Why it is used 2) When it is normally used and 3) How it should be used.

Example Code:
Source: viewtopic.php?t=16283

Code: Select all

class backend extends Object{
   
   function createObject($_classname, $_params='')
    {
   //echo $_classname;exit;
       // include file if it's not already been included
        if (!class_exists($_classname)) require_once("class.".$_classname.".php");
        if (!is_array($_params)) $object = new $_classname;
        else $object =& new $_classname($_params);
       
        // Assign a reference to the application object to the class so App is always accesable
        $object->front =& $this;
        return $object;
    }

//I have some other functions in here such as error function, ...
}
-Nay
User avatar
patrikG
DevNet Master
Posts: 4235
Joined: Thu Aug 15, 2002 5:53 am
Location: Sussex, UK

Post by patrikG »

That looks very much like an iterator pattern there. A reference is very much what the Manual says it is - more or less cojoined twins (or triplets etc), but variables.

Example:

Code: Select all

$a=5;
$b=&$a;
$a++;
echo 'B: '.$b;
// will echo 6;
You have not increased $b. You have increased $a. But because $b is a reference (a direct link) to $a, the value of $b is that of $a. When $a changes, $b changes.

Does that make sense?
penguinboy
Forum Contributor
Posts: 171
Joined: Thu Nov 07, 2002 11:25 am

Post by penguinboy »

Nay
Forum Regular
Posts: 951
Joined: Fri Jun 20, 2003 11:03 am
Location: Brisbane, Australia

Post by Nay »

Yeah a little better now. But:

Code: Select all

<?php
function foo($var)
{
   $var++;
}

function bar(&$var)
{            // 'built in' reference
   $var++;   // any variable passed through bar()
}            // will automatically be a reference

$a=0;
$b=0;
$c=0;
$d=0;

foo(&$a);   // asigning reference
foo($b);   // no reference
bar($c);   // no reference
bar(&$d);   // asigning reference

print $a;   // 1
print $b;   // 0, no reference
print $c;   // 1
print $d;   // 1
?>
When the '&' is used, where exactly are '$a', '$b' referenced to?

-Nay
penguinboy
Forum Contributor
Posts: 171
Joined: Thu Nov 07, 2002 11:25 am

Post by penguinboy »

Well, the way I understand it is:

Code: Select all

$a = 5; // $a points to a place in memory 
$b =& $a; // $b referenced to the same place as $a


function bar(&$var) // referenced to the location of the passed var passed
{
   $var++;
}
Nay
Forum Regular
Posts: 951
Joined: Fri Jun 20, 2003 11:03 am
Location: Brisbane, Australia

Post by Nay »

So If it is referenced to the location of the variable, that would be doing like:

Code: Select all

$a = 0;
$a += 1;

// or

$a = 0;
function bar(&$var) {
   $var++;
}
bar($a);

// and both results in a being 1
I tested that out and it did return $a as 1. Anyhow, the last part of my questions, I was reading:

http://www.php-center.de/en-html-manual ... eturn.html

Code: Select all

function &find_var ($param)
{
    ...code...
    return $found_var;
}

$foo =& find_var ($bar);
$foo->x = 2;
I tried some experimental code that I thought the function was supposed to do but it didn't work out so well.

-Nay
timvw
DevNet Master
Posts: 4897
Joined: Mon Jan 19, 2004 11:11 pm
Location: Leuven, Belgium

Post by timvw »

If i remember it well, it goes like this (in short):

Consider your memory as a pile of boxes that contain data

2 [data2]
1 [data1]
0 [data0]

Now the same goes for a $a (alias for place 3945) that contains value dataA

$a=3945 [dataA]
...
2 [data2]
1 [data1]
0 [data0]

Each time a function is called, all the arguments are copied into reserved place in your memory. As you might have noticed, if you alter such a parameter, it only changes inside the function (because you are using a copy). Sometimes it is usefull to alter the data, instead a copy of that data (for example really large blocks of data). Thus, instead of passing the contents of the box that $a points to, you tell where the data can be found.

In this case, &$a would return 3945. And the function would know it has to look for the data in the memory box #3945
eletrium
Forum Commoner
Posts: 34
Joined: Tue Feb 10, 2004 3:38 pm

Post by eletrium »

Uh, keep in mind references are only really useful for passing large amounts of data easier. A reference is a Hex number, pretty much an integer. An "Object" is just a single reference with tools to access the rest of it.

Object ComplexThing
variable A Interger
Variable B String
Variable C SubObject
Variable D Float

Function doSomethignwithObject( aComplexThing )

*points up*

If you passed all that data in that object individually, it would take a lot more convoluted code. Not to mention it could eat lots of time. When you pass an object, you are passing the reference to that object..... which is one of the reasons why lots of programmers use objects.
timvw
DevNet Master
Posts: 4897
Joined: Mon Jan 19, 2004 11:11 pm
Location: Leuven, Belgium

Post by timvw »

Classes don't have to be passed by referenced per definition.
I haven't had the time to look up how php does it, but i know that in c++ you can pass them by value too and java passes a copy of the reference to that object.

but as said before: references to data can be usefull to avoid making copies of large data blocks and to allow the programmer to modify more than one variable in a function.
McGruff
DevNet Master
Posts: 2893
Joined: Thu Jan 30, 2003 8:26 pm
Location: Glasgow, Scotland

Post by McGruff »

In OOP, you usually do not get the behaviour you want if you don't pass by reference.

If you copy an object changes in state for the original object are not updated in the copy.

If you pass a reference to the object, there's only ever a single object which different vars point towards. Wherever one of the object's interface methods is called, and the original object changes state, you can be sure that all your other referenced vars reflect this new state. Usually that's what you want.

Suppose you have an ErrorLog class which you intend should gather any errors in the script and later log these to file. ErrorLog is used by a whole bunch of other objects.

If ErrorLog is passed around by reference you get the intended behaviour of a single errors class which collects info from all the other objects.

If the errors class was instead being copied to the other objects, you'd have to collect each of the separate errors classes (somehow) and log the contents of each in turn - very messy.

One of the best practical guides on OOP referencing comes from the eclipse read me:
- To get Java-like object behavior, ALWAYS use references when:
- Creating objects : $object =& new Object;
- Passing objects : function receiveObject(&$object) { //... }
- Returning objects: function &returnObject() { return $object; }

PHP's default behavior is to create copies, which is almost always NOT what
you really want. When some object contains a reference to a second object
and you create a copy of the first object instead of a reference, this copy
will NOT share the reference to the second object, but will hold a copy of
that object instead. This can (and will) lead to strange and undesired
behavior. To summarize:

function &getNiftyComputationResult(&$iterator))
{
$result =& new NiftyComputationResult;
for ($iterator->reset(); $iterator->isValid(); $it->next())
{
$result->add($iterator->getCurrent());
}
return $result;
}

$it =& new ArrayIterator(array(8, 5, 3, 9, 6, 1, 7, 4, 2));
$result =& getNiftyComputationResult($it);

It takes a while to get used to, but it is truly the only way to correctly
handle objects in PHP 4 ('correctly' meaning 'Java-like' in this context).
fastfingertips
Forum Contributor
Posts: 242
Joined: Sun Dec 28, 2003 1:40 am
Contact:

Post by fastfingertips »

The referrencing is just a synonim.
You may think to it like this, you may use this in may applications, but in PHP i think is related to avoid overloading a variable.
User avatar
patrikG
DevNet Master
Posts: 4235
Joined: Thu Aug 15, 2002 5:53 am
Location: Sussex, UK

Post by patrikG »

Generally a good, general introduction regarding OOP, patterns and PHP:

http://www.horde.org/papers/kongress200 ... _patterns/

A good tutorial regarding references is

http://www.phppatterns.com/index.php/ar ... ew/23/1/2/
Post Reply